]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mips/mips.md
gcc/
[thirdparty/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, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;; 2011, 2012
5 ;; Free Software Foundation, Inc.
6 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
7 ;; Changes by Michael Meissner, meissner@osf.org
8 ;; 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
9 ;; Brendan Eich, brendan@microunity.com.
10
11 ;; This file is part of GCC.
12
13 ;; GCC is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 3, or (at your option)
16 ;; any later version.
17
18 ;; GCC is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
22
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GCC; see the file COPYING3. If not see
25 ;; <http://www.gnu.org/licenses/>.
26
27 (define_enum "processor" [
28 r3000
29 4kc
30 4kp
31 5kc
32 5kf
33 20kc
34 24kc
35 24kf2_1
36 24kf1_1
37 74kc
38 74kf2_1
39 74kf1_1
40 74kf3_2
41 loongson_2e
42 loongson_2f
43 loongson_3a
44 m4k
45 octeon
46 octeon2
47 r3900
48 r6000
49 r4000
50 r4100
51 r4111
52 r4120
53 r4130
54 r4300
55 r4600
56 r4650
57 r4700
58 r5000
59 r5400
60 r5500
61 r7000
62 r8000
63 r9000
64 r10000
65 sb1
66 sb1a
67 sr71000
68 xlr
69 xlp
70 ])
71
72 (define_c_enum "unspec" [
73 ;; Unaligned accesses.
74 UNSPEC_LOAD_LEFT
75 UNSPEC_LOAD_RIGHT
76 UNSPEC_STORE_LEFT
77 UNSPEC_STORE_RIGHT
78
79 ;; Floating-point moves.
80 UNSPEC_LOAD_LOW
81 UNSPEC_LOAD_HIGH
82 UNSPEC_STORE_WORD
83 UNSPEC_MFHC1
84 UNSPEC_MTHC1
85
86 ;; HI/LO moves.
87 UNSPEC_MFHI
88 UNSPEC_MTHI
89 UNSPEC_SET_HILO
90
91 ;; GP manipulation.
92 UNSPEC_LOADGP
93 UNSPEC_COPYGP
94 UNSPEC_MOVE_GP
95 UNSPEC_POTENTIAL_CPRESTORE
96 UNSPEC_CPRESTORE
97 UNSPEC_RESTORE_GP
98 UNSPEC_EH_RETURN
99 UNSPEC_GP
100 UNSPEC_SET_GOT_VERSION
101 UNSPEC_UPDATE_GOT_VERSION
102
103 ;; Symbolic accesses.
104 UNSPEC_LOAD_CALL
105 UNSPEC_LOAD_GOT
106 UNSPEC_TLS_LDM
107 UNSPEC_TLS_GET_TP
108 UNSPEC_UNSHIFTED_HIGH
109
110 ;; MIPS16 constant pools.
111 UNSPEC_ALIGN
112 UNSPEC_CONSTTABLE_INT
113 UNSPEC_CONSTTABLE_FLOAT
114
115 ;; Blockage and synchronisation.
116 UNSPEC_BLOCKAGE
117 UNSPEC_CLEAR_HAZARD
118 UNSPEC_RDHWR
119 UNSPEC_SYNCI
120 UNSPEC_SYNC
121
122 ;; Cache manipulation.
123 UNSPEC_MIPS_CACHE
124 UNSPEC_R10K_CACHE_BARRIER
125
126 ;; Interrupt handling.
127 UNSPEC_ERET
128 UNSPEC_DERET
129 UNSPEC_DI
130 UNSPEC_EHB
131 UNSPEC_RDPGPR
132 UNSPEC_COP0
133
134 ;; Used in a call expression in place of args_size. It's present for PIC
135 ;; indirect calls where it contains args_size and the function symbol.
136 UNSPEC_CALL_ATTR
137
138 ;; MIPS16 casesi jump table dispatch.
139 UNSPEC_CASESI_DISPATCH
140
141 ;; Stack checking.
142 UNSPEC_PROBE_STACK_RANGE
143 ])
144
145 (define_constants
146 [(TLS_GET_TP_REGNUM 3)
147 (MIPS16_T_REGNUM 24)
148 (PIC_FUNCTION_ADDR_REGNUM 25)
149 (RETURN_ADDR_REGNUM 31)
150 (CPRESTORE_SLOT_REGNUM 76)
151 (GOT_VERSION_REGNUM 79)
152
153 ;; PIC long branch sequences are never longer than 100 bytes.
154 (MAX_PIC_BRANCH_LENGTH 100)
155 ]
156 )
157
158 (include "predicates.md")
159 (include "constraints.md")
160 \f
161 ;; ....................
162 ;;
163 ;; Attributes
164 ;;
165 ;; ....................
166
167 (define_attr "got" "unset,xgot_high,load"
168 (const_string "unset"))
169
170 ;; For jal instructions, this attribute is DIRECT when the target address
171 ;; is symbolic and INDIRECT when it is a register.
172 (define_attr "jal" "unset,direct,indirect"
173 (const_string "unset"))
174
175 ;; This attribute is YES if the instruction is a jal macro (not a
176 ;; real jal instruction).
177 ;;
178 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
179 ;; an instruction to restore $gp. Direct jals are also macros for
180 ;; !TARGET_ABSOLUTE_JUMPS because they first load the target address
181 ;; into a register.
182 (define_attr "jal_macro" "no,yes"
183 (cond [(eq_attr "jal" "direct")
184 (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS
185 ? JAL_MACRO_YES : JAL_MACRO_NO)")
186 (eq_attr "jal" "indirect")
187 (symbol_ref "(TARGET_CALL_CLOBBERED_GP
188 ? JAL_MACRO_YES : JAL_MACRO_NO)")]
189 (const_string "no")))
190
191 ;; Classification of moves, extensions and truncations. Most values
192 ;; are as for "type" (see below) but there are also the following
193 ;; move-specific values:
194 ;;
195 ;; constN move an N-constraint integer into a MIPS16 register
196 ;; sll0 "sll DEST,SRC,0", which on 64-bit targets is guaranteed
197 ;; to produce a sign-extended DEST, even if SRC is not
198 ;; properly sign-extended
199 ;; ext_ins EXT, DEXT, INS or DINS instruction
200 ;; andi a single ANDI instruction
201 ;; loadpool move a constant into a MIPS16 register by loading it
202 ;; from the pool
203 ;; shift_shift a shift left followed by a shift right
204 ;;
205 ;; This attribute is used to determine the instruction's length and
206 ;; scheduling type. For doubleword moves, the attribute always describes
207 ;; the split instructions; in some cases, it is more appropriate for the
208 ;; scheduling type to be "multi" instead.
209 (define_attr "move_type"
210 "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,imul,move,fmove,
211 const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
212 shift_shift"
213 (const_string "unknown"))
214
215 (define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor"
216 (const_string "unknown"))
217
218 ;; Main data type used by the insn
219 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
220 (const_string "unknown"))
221
222 ;; True if the main data type is twice the size of a word.
223 (define_attr "dword_mode" "no,yes"
224 (cond [(and (eq_attr "mode" "DI,DF")
225 (not (match_test "TARGET_64BIT")))
226 (const_string "yes")
227
228 (and (eq_attr "mode" "TI,TF")
229 (match_test "TARGET_64BIT"))
230 (const_string "yes")]
231 (const_string "no")))
232
233 ;; Attributes describing a sync loop. These loops have the form:
234 ;;
235 ;; if (RELEASE_BARRIER == YES) sync
236 ;; 1: OLDVAL = *MEM
237 ;; if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
238 ;; CMP = 0 [delay slot]
239 ;; $TMP1 = OLDVAL & EXCLUSIVE_MASK
240 ;; $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
241 ;; $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
242 ;; $AT |= $TMP1 | $TMP3
243 ;; if (!commit (*MEM = $AT)) goto 1.
244 ;; if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
245 ;; CMP = 1
246 ;; if (ACQUIRE_BARRIER == YES) sync
247 ;; 2:
248 ;;
249 ;; where "$" values are temporaries and where the other values are
250 ;; specified by the attributes below. Values are specified as operand
251 ;; numbers and insns are specified as enums. If no operand number is
252 ;; specified, the following values are used instead:
253 ;;
254 ;; - OLDVAL: $AT
255 ;; - CMP: NONE
256 ;; - NEWVAL: $AT
257 ;; - INCLUSIVE_MASK: -1
258 ;; - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
259 ;; - EXCLUSIVE_MASK: 0
260 ;;
261 ;; MEM and INSN1_OP2 are required.
262 ;;
263 ;; Ideally, the operand attributes would be integers, with -1 meaning "none",
264 ;; but the gen* programs don't yet support that.
265 (define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
266 (define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
267 (define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
268 (define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
269 (define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
270 (define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
271 (define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
272 (define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
273 (define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
274 (const_string "move"))
275 (define_attr "sync_insn2" "nop,and,xor,not"
276 (const_string "nop"))
277 ;; Memory model specifier.
278 ;; "0"-"9" values specify the operand that stores the memory model value.
279 ;; "10" specifies MEMMODEL_ACQ_REL,
280 ;; "11" specifies MEMMODEL_ACQUIRE.
281 (define_attr "sync_memmodel" "" (const_int 10))
282
283 ;; Accumulator operand for madd patterns.
284 (define_attr "accum_in" "none,0,1,2,3,4,5" (const_string "none"))
285
286 ;; Classification of each insn.
287 ;; branch conditional branch
288 ;; jump unconditional jump
289 ;; call unconditional call
290 ;; load load instruction(s)
291 ;; fpload floating point load
292 ;; fpidxload floating point indexed load
293 ;; store store instruction(s)
294 ;; fpstore floating point store
295 ;; fpidxstore floating point indexed store
296 ;; prefetch memory prefetch (register + offset)
297 ;; prefetchx memory indexed prefetch (register + register)
298 ;; condmove conditional moves
299 ;; mtc transfer to coprocessor
300 ;; mfc transfer from coprocessor
301 ;; mthi transfer to a hi register
302 ;; mtlo transfer to a lo register
303 ;; mfhi transfer from a hi register
304 ;; mflo transfer from a lo register
305 ;; const load constant
306 ;; arith integer arithmetic instructions
307 ;; logical integer logical instructions
308 ;; shift integer shift instructions
309 ;; slt set less than instructions
310 ;; signext sign extend instructions
311 ;; clz the clz and clo instructions
312 ;; pop the pop instruction
313 ;; trap trap if instructions
314 ;; imul integer multiply 2 operands
315 ;; imul3 integer multiply 3 operands
316 ;; imul3nc integer multiply 3 operands without clobbering HI/LO
317 ;; imadd integer multiply-add
318 ;; idiv integer divide 2 operands
319 ;; idiv3 integer divide 3 operands
320 ;; move integer register move ({,D}ADD{,U} with rt = 0)
321 ;; fmove floating point register move
322 ;; fadd floating point add/subtract
323 ;; fmul floating point multiply
324 ;; fmadd floating point multiply-add
325 ;; fdiv floating point divide
326 ;; frdiv floating point reciprocal divide
327 ;; frdiv1 floating point reciprocal divide step 1
328 ;; frdiv2 floating point reciprocal divide step 2
329 ;; fabs floating point absolute value
330 ;; fneg floating point negation
331 ;; fcmp floating point compare
332 ;; fcvt floating point convert
333 ;; fsqrt floating point square root
334 ;; frsqrt floating point reciprocal square root
335 ;; frsqrt1 floating point reciprocal square root step1
336 ;; frsqrt2 floating point reciprocal square root step2
337 ;; dspmac DSP MAC instructions not saturating the accumulator
338 ;; dspmacsat DSP MAC instructions that saturate the accumulator
339 ;; accext DSP accumulator extract instructions
340 ;; accmod DSP accumulator modify instructions
341 ;; dspalu DSP ALU instructions not saturating the result
342 ;; dspalusat DSP ALU instructions that saturate the result
343 ;; multi multiword sequence (or user asm statements)
344 ;; atomic atomic memory update instruction
345 ;; syncloop memory atomic operation implemented as a sync loop
346 ;; nop no operation
347 ;; ghost an instruction that produces no real code
348 (define_attr "type"
349 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,
350 prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
351 shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
352 fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
353 frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
354 multi,atomic,syncloop,nop,ghost"
355 (cond [(eq_attr "jal" "!unset") (const_string "call")
356 (eq_attr "got" "load") (const_string "load")
357
358 (eq_attr "alu_type" "add,sub") (const_string "arith")
359
360 (eq_attr "alu_type" "not,nor,and,or,xor") (const_string "logical")
361
362 ;; If a doubleword move uses these expensive instructions,
363 ;; it is usually better to schedule them in the same way
364 ;; as the singleword form, rather than as "multi".
365 (eq_attr "move_type" "load") (const_string "load")
366 (eq_attr "move_type" "fpload") (const_string "fpload")
367 (eq_attr "move_type" "store") (const_string "store")
368 (eq_attr "move_type" "fpstore") (const_string "fpstore")
369 (eq_attr "move_type" "mtc") (const_string "mtc")
370 (eq_attr "move_type" "mfc") (const_string "mfc")
371 (eq_attr "move_type" "mtlo") (const_string "mtlo")
372 (eq_attr "move_type" "mflo") (const_string "mflo")
373
374 ;; These types of move are always single insns.
375 (eq_attr "move_type" "imul") (const_string "imul")
376 (eq_attr "move_type" "fmove") (const_string "fmove")
377 (eq_attr "move_type" "loadpool") (const_string "load")
378 (eq_attr "move_type" "signext") (const_string "signext")
379 (eq_attr "move_type" "ext_ins") (const_string "arith")
380 (eq_attr "move_type" "arith") (const_string "arith")
381 (eq_attr "move_type" "logical") (const_string "logical")
382 (eq_attr "move_type" "sll0") (const_string "shift")
383 (eq_attr "move_type" "andi") (const_string "logical")
384
385 ;; These types of move are always split.
386 (eq_attr "move_type" "constN,shift_shift")
387 (const_string "multi")
388
389 ;; These types of move are split for doubleword modes only.
390 (and (eq_attr "move_type" "move,const")
391 (eq_attr "dword_mode" "yes"))
392 (const_string "multi")
393 (eq_attr "move_type" "move") (const_string "move")
394 (eq_attr "move_type" "const") (const_string "const")
395 (eq_attr "sync_mem" "!none") (const_string "syncloop")]
396 (const_string "unknown")))
397
398 ;; Mode for conversion types (fcvt)
399 ;; I2S integer to float single (SI/DI to SF)
400 ;; I2D integer to float double (SI/DI to DF)
401 ;; S2I float to integer (SF to SI/DI)
402 ;; D2I float to integer (DF to SI/DI)
403 ;; D2S double to float single
404 ;; S2D float single to double
405
406 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
407 (const_string "unknown"))
408
409 ;; Is this an extended instruction in mips16 mode?
410 (define_attr "extended_mips16" "no,yes"
411 (if_then_else (ior (eq_attr "move_type" "sll0")
412 (eq_attr "type" "branch")
413 (eq_attr "jal" "direct"))
414 (const_string "yes")
415 (const_string "no")))
416
417 ;; Length of instruction in bytes.
418 (define_attr "length" ""
419 (cond [;; Direct branch instructions have a range of [-0x20000,0x1fffc],
420 ;; relative to the address of the delay slot. If a branch is
421 ;; outside this range, we have a choice of two sequences.
422 ;; For PIC, an out-of-range branch like:
423 ;;
424 ;; bne r1,r2,target
425 ;; dslot
426 ;;
427 ;; becomes the equivalent of:
428 ;;
429 ;; beq r1,r2,1f
430 ;; dslot
431 ;; la $at,target
432 ;; jr $at
433 ;; nop
434 ;; 1:
435 ;;
436 ;; The non-PIC case is similar except that we use a direct
437 ;; jump instead of an la/jr pair. Since the target of this
438 ;; jump is an absolute 28-bit bit address (the other bits
439 ;; coming from the address of the delay slot) this form cannot
440 ;; cross a 256MB boundary. We could provide the option of
441 ;; using la/jr in this case too, but we do not do so at
442 ;; present.
443 ;;
444 ;; The value we specify here does not account for the delay slot
445 ;; instruction, whose length is added separately. If the RTL
446 ;; pattern has no explicit delay slot, mips_adjust_insn_length
447 ;; will add the length of the implicit nop. The range of
448 ;; [-0x20000, 0x1fffc] from the address of the delay slot
449 ;; therefore translates to a range of:
450 ;;
451 ;; [-(0x20000 - sizeof (branch)), 0x1fffc - sizeof (slot)]
452 ;; == [-0x1fffc, 0x1fff8]
453 ;;
454 ;; from the shorten_branches reference address.
455 (and (eq_attr "type" "branch")
456 (not (match_test "TARGET_MIPS16")))
457 (cond [(and (le (minus (match_dup 0) (pc)) (const_int 131064))
458 (le (minus (pc) (match_dup 0)) (const_int 131068)))
459 (const_int 4)
460
461 ;; The non-PIC case: branch, first delay slot, and J.
462 (match_test "TARGET_ABSOLUTE_JUMPS")
463 (const_int 12)]
464
465 ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
466 ;; mips_adjust_insn_length substitutes the correct length.
467 ;;
468 ;; Note that we can't simply use (symbol_ref ...) here
469 ;; because genattrtab needs to know the maximum length
470 ;; of an insn.
471 (const_int MAX_PIC_BRANCH_LENGTH))
472
473 ;; An unextended MIPS16 branch has a range of [-0x100, 0xfe]
474 ;; from the address of the following instruction, which leads
475 ;; to a range of:
476 ;;
477 ;; [-(0x100 - sizeof (branch)), 0xfe]
478 ;; == [-0xfe, 0xfe]
479 ;;
480 ;; from the shorten_branches reference address. Extended branches
481 ;; likewise have a range of [-0x10000, 0xfffe] from the address
482 ;; of the following instruction, which leads to a range of:
483 ;;
484 ;; [-(0x10000 - sizeof (branch)), 0xfffe]
485 ;; == [-0xfffc, 0xfffe]
486 ;;
487 ;; from the reference address.
488 ;;
489 ;; When a branch is out of range, mips_reorg splits it into a form
490 ;; that uses in-range branches. There are four basic sequences:
491 ;;
492 ;; (1) Absolute addressing with a readable text segment
493 ;; (32-bit addresses):
494 ;;
495 ;; b... foo 2 bytes
496 ;; move $1,$2 2 bytes
497 ;; lw $2,label 2 bytes
498 ;; jr $2 2 bytes
499 ;; move $2,$1 2 bytes
500 ;; .align 2 0 or 2 bytes
501 ;; label:
502 ;; .word target 4 bytes
503 ;; foo:
504 ;; (16 bytes in the worst case)
505 ;;
506 ;; (2) Absolute addressing with a readable text segment
507 ;; (64-bit addresses):
508 ;;
509 ;; b... foo 2 bytes
510 ;; move $1,$2 2 bytes
511 ;; ld $2,label 2 bytes
512 ;; jr $2 2 bytes
513 ;; move $2,$1 2 bytes
514 ;; .align 3 0 to 6 bytes
515 ;; label:
516 ;; .dword target 8 bytes
517 ;; foo:
518 ;; (24 bytes in the worst case)
519 ;;
520 ;; (3) Absolute addressing without a readable text segment
521 ;; (which requires 32-bit addresses at present):
522 ;;
523 ;; b... foo 2 bytes
524 ;; move $1,$2 2 bytes
525 ;; lui $2,%hi(target) 4 bytes
526 ;; sll $2,8 2 bytes
527 ;; sll $2,8 2 bytes
528 ;; addiu $2,%lo(target) 4 bytes
529 ;; jr $2 2 bytes
530 ;; move $2,$1 2 bytes
531 ;; foo:
532 ;; (20 bytes)
533 ;;
534 ;; (4) PIC addressing (which requires 32-bit addresses at present):
535 ;;
536 ;; b... foo 2 bytes
537 ;; move $1,$2 2 bytes
538 ;; lw $2,cprestore 0, 2 or 4 bytes
539 ;; lw $2,%got(target)($2) 4 bytes
540 ;; addiu $2,%lo(target) 4 bytes
541 ;; jr $2 2 bytes
542 ;; move $2,$1 2 bytes
543 ;; foo:
544 ;; (20 bytes in the worst case)
545 ;;
546 ;; Note that the conditions test adjusted lengths, whereas the
547 ;; result is an unadjusted length, and is thus twice the true value.
548 (and (eq_attr "type" "branch")
549 (match_test "TARGET_MIPS16"))
550 (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
551 (le (minus (pc) (match_dup 0)) (const_int 254)))
552 (const_int 4)
553 (and (le (minus (match_dup 0) (pc)) (const_int 65534))
554 (le (minus (pc) (match_dup 0)) (const_int 65532)))
555 (const_int 8)
556 (and (match_test "TARGET_ABICALLS")
557 (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
558 (const_int 40)
559 (match_test "Pmode == SImode")
560 (const_int 32)
561 ] (const_int 48))
562
563 (and (eq_attr "extended_mips16" "yes")
564 (match_test "TARGET_MIPS16"))
565 (const_int 8)
566
567 ;; "Ghost" instructions occupy no space.
568 (eq_attr "type" "ghost")
569 (const_int 0)
570
571 (eq_attr "got" "load")
572 (if_then_else (match_test "TARGET_MIPS16")
573 (const_int 8)
574 (const_int 4))
575 (eq_attr "got" "xgot_high")
576 (const_int 8)
577
578 ;; In general, constant-pool loads are extended instructions.
579 (eq_attr "move_type" "loadpool")
580 (const_int 8)
581
582 ;; SHIFT_SHIFTs are decomposed into two separate instructions.
583 ;; They are extended instructions on MIPS16 targets.
584 (eq_attr "move_type" "shift_shift")
585 (if_then_else (match_test "TARGET_MIPS16")
586 (const_int 16)
587 (const_int 8))
588
589 ;; Check for doubleword moves that are decomposed into two
590 ;; instructions.
591 (and (eq_attr "move_type" "mtc,mfc,mtlo,mflo,move")
592 (eq_attr "dword_mode" "yes"))
593 (const_int 8)
594
595 ;; Doubleword CONST{,N} moves are split into two word
596 ;; CONST{,N} moves.
597 (and (eq_attr "move_type" "const,constN")
598 (eq_attr "dword_mode" "yes"))
599 (symbol_ref "mips_split_const_insns (operands[1]) * 4")
600
601 ;; Otherwise, constants, loads and stores are handled by external
602 ;; routines.
603 (eq_attr "move_type" "const,constN")
604 (symbol_ref "mips_const_insns (operands[1]) * 4")
605 (eq_attr "move_type" "load,fpload")
606 (symbol_ref "mips_load_store_insns (operands[1], insn) * 4")
607 (eq_attr "move_type" "store,fpstore")
608 (cond [(not (match_test "TARGET_FIX_24K"))
609 (symbol_ref "mips_load_store_insns (operands[0], insn) * 4")]
610 (symbol_ref "mips_load_store_insns (operands[0], insn) * 4 + 4"))
611
612 ;; In the worst case, a call macro will take 8 instructions:
613 ;;
614 ;; lui $25,%call_hi(FOO)
615 ;; addu $25,$25,$28
616 ;; lw $25,%call_lo(FOO)($25)
617 ;; nop
618 ;; jalr $25
619 ;; nop
620 ;; lw $gp,X($sp)
621 ;; nop
622 (eq_attr "jal_macro" "yes")
623 (const_int 32)
624
625 ;; Various VR4120 errata require a nop to be inserted after a macc
626 ;; instruction. The assembler does this for us, so account for
627 ;; the worst-case length here.
628 (and (eq_attr "type" "imadd")
629 (match_test "TARGET_FIX_VR4120"))
630 (const_int 8)
631
632 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
633 ;; the result of the second one is missed. The assembler should work
634 ;; around this by inserting a nop after the first dmult.
635 (and (eq_attr "type" "imul,imul3")
636 (and (eq_attr "mode" "DI")
637 (match_test "TARGET_FIX_VR4120")))
638 (const_int 8)
639
640 (eq_attr "type" "idiv,idiv3")
641 (symbol_ref "mips_idiv_insns () * 4")
642
643 (not (eq_attr "sync_mem" "none"))
644 (symbol_ref "mips_sync_loop_insns (insn, operands) * 4")
645 ] (const_int 4)))
646
647 ;; Attribute describing the processor.
648 (define_enum_attr "cpu" "processor"
649 (const (symbol_ref "mips_tune")))
650
651 ;; The type of hardware hazard associated with this instruction.
652 ;; DELAY means that the next instruction cannot read the result
653 ;; of this one. HILO means that the next two instructions cannot
654 ;; write to HI or LO.
655 (define_attr "hazard" "none,delay,hilo"
656 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
657 (match_test "ISA_HAS_LOAD_DELAY"))
658 (const_string "delay")
659
660 (and (eq_attr "type" "mfc,mtc")
661 (match_test "ISA_HAS_XFER_DELAY"))
662 (const_string "delay")
663
664 (and (eq_attr "type" "fcmp")
665 (match_test "ISA_HAS_FCMP_DELAY"))
666 (const_string "delay")
667
668 ;; The r4000 multiplication patterns include an mflo instruction.
669 (and (eq_attr "type" "imul")
670 (match_test "TARGET_FIX_R4000"))
671 (const_string "hilo")
672
673 (and (eq_attr "type" "mfhi,mflo")
674 (not (match_test "ISA_HAS_HILO_INTERLOCKS")))
675 (const_string "hilo")]
676 (const_string "none")))
677
678 ;; Is it a single instruction?
679 (define_attr "single_insn" "no,yes"
680 (symbol_ref "(get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)
681 ? SINGLE_INSN_YES : SINGLE_INSN_NO)"))
682
683 ;; Can the instruction be put into a delay slot?
684 (define_attr "can_delay" "no,yes"
685 (if_then_else (and (eq_attr "type" "!branch,call,jump")
686 (and (eq_attr "hazard" "none")
687 (eq_attr "single_insn" "yes")))
688 (const_string "yes")
689 (const_string "no")))
690
691 ;; Attribute defining whether or not we can use the branch-likely
692 ;; instructions.
693 (define_attr "branch_likely" "no,yes"
694 (if_then_else (match_test "GENERATE_BRANCHLIKELY")
695 (const_string "yes")
696 (const_string "no")))
697
698 ;; True if an instruction might assign to hi or lo when reloaded.
699 ;; This is used by the TUNE_MACC_CHAINS code.
700 (define_attr "may_clobber_hilo" "no,yes"
701 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthi,mtlo")
702 (const_string "yes")
703 (const_string "no")))
704
705 ;; Describe a user's asm statement.
706 (define_asm_attributes
707 [(set_attr "type" "multi")
708 (set_attr "can_delay" "no")])
709 \f
710 ;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
711 ;; from the same template.
712 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
713
714 ;; A copy of GPR that can be used when a pattern has two independent
715 ;; modes.
716 (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
717
718 ;; This mode iterator allows :HILO to be used as the mode of the
719 ;; concatenated HI and LO registers.
720 (define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")])
721
722 ;; This mode iterator allows :P to be used for patterns that operate on
723 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
724 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
725
726 ;; This mode iterator allows :MOVECC to be used anywhere that a
727 ;; conditional-move-type condition is needed.
728 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT")
729 (CC "TARGET_HARD_FLOAT && !TARGET_LOONGSON_2EF")])
730
731 ;; 32-bit integer moves for which we provide move patterns.
732 (define_mode_iterator IMOVE32
733 [SI
734 (V2HI "TARGET_DSP")
735 (V4QI "TARGET_DSP")
736 (V2HQ "TARGET_DSP")
737 (V2UHQ "TARGET_DSP")
738 (V2HA "TARGET_DSP")
739 (V2UHA "TARGET_DSP")
740 (V4QQ "TARGET_DSP")
741 (V4UQQ "TARGET_DSP")])
742
743 ;; 64-bit modes for which we provide move patterns.
744 (define_mode_iterator MOVE64
745 [DI DF
746 (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")
747 (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
748 (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")
749 (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")])
750
751 ;; 128-bit modes for which we provide move patterns on 64-bit targets.
752 (define_mode_iterator MOVE128 [TI TF])
753
754 ;; This mode iterator allows the QI and HI extension patterns to be
755 ;; defined from the same template.
756 (define_mode_iterator SHORT [QI HI])
757
758 ;; Likewise the 64-bit truncate-and-shift patterns.
759 (define_mode_iterator SUBDI [QI HI SI])
760
761 ;; This mode iterator allows :ANYF to be used wherever a scalar or vector
762 ;; floating-point mode is allowed.
763 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
764 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
765 (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
766
767 ;; Like ANYF, but only applies to scalar modes.
768 (define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
769 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
770
771 ;; A floating-point mode for which moves involving FPRs may need to be split.
772 (define_mode_iterator SPLITF
773 [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
774 (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
775 (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
776 (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
777 (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
778 (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS")
779 (TF "TARGET_64BIT && TARGET_FLOAT64")])
780
781 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
782 ;; 32-bit version and "dsubu" in the 64-bit version.
783 (define_mode_attr d [(SI "") (DI "d")
784 (QQ "") (HQ "") (SQ "") (DQ "d")
785 (UQQ "") (UHQ "") (USQ "") (UDQ "d")
786 (HA "") (SA "") (DA "d")
787 (UHA "") (USA "") (UDA "d")])
788
789 ;; Same as d but upper-case.
790 (define_mode_attr D [(SI "") (DI "D")
791 (QQ "") (HQ "") (SQ "") (DQ "D")
792 (UQQ "") (UHQ "") (USQ "") (UDQ "D")
793 (HA "") (SA "") (DA "D")
794 (UHA "") (USA "") (UDA "D")])
795
796 ;; This attribute gives the length suffix for a load or store instruction.
797 ;; The same suffixes work for zero and sign extensions.
798 (define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")])
799 (define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")])
800
801 ;; This attributes gives the mode mask of a SHORT.
802 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
803
804 ;; Mode attributes for GPR loads.
805 (define_mode_attr load [(SI "lw") (DI "ld")])
806 ;; Instruction names for stores.
807 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")])
808
809 ;; Similarly for MIPS IV indexed FPR loads and stores.
810 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
811 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
812
813 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
814 ;; are different. Some forms of unextended addiu have an 8-bit immediate
815 ;; field but the equivalent daddiu has only a 5-bit field.
816 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
817
818 ;; This attribute gives the best constraint to use for registers of
819 ;; a given mode.
820 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
821
822 ;; This attribute gives the format suffix for floating-point operations.
823 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
824
825 ;; This attribute gives the upper-case mode name for one unit of a
826 ;; floating-point mode.
827 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
828
829 ;; This attribute gives the integer mode that has the same size as a
830 ;; fixed-point mode.
831 (define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
832 (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
833 (HA "HI") (SA "SI") (DA "DI")
834 (UHA "HI") (USA "SI") (UDA "DI")
835 (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
836 (V2HQ "SI") (V2HA "SI")])
837
838 ;; This attribute gives the integer mode that has half the size of
839 ;; the controlling mode.
840 (define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI")
841 (V2SI "SI") (V4HI "SI") (V8QI "SI")
842 (TF "DI")])
843
844 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
845 ;;
846 ;; In certain cases, div.s and div.ps may have a rounding error
847 ;; and/or wrong inexact flag.
848 ;;
849 ;; Therefore, we only allow div.s if not working around SB-1 rev2
850 ;; errata or if a slight loss of precision is OK.
851 (define_mode_attr divide_condition
852 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
853 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
854
855 ;; This attribute gives the conditions under which SQRT.fmt instructions
856 ;; can be used.
857 (define_mode_attr sqrt_condition
858 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
859
860 ;; This attribute gives the conditions under which RECIP.fmt and RSQRT.fmt
861 ;; instructions can be used. The MIPS32 and MIPS64 ISAs say that RECIP.D
862 ;; and RSQRT.D are unpredictable when doubles are stored in pairs of FPRs,
863 ;; so for safety's sake, we apply this restriction to all targets.
864 (define_mode_attr recip_condition
865 [(SF "ISA_HAS_FP4")
866 (DF "ISA_HAS_FP4 && TARGET_FLOAT64")
867 (V2SF "TARGET_SB1")])
868
869 ;; This code iterator allows signed and unsigned widening multiplications
870 ;; to use the same template.
871 (define_code_iterator any_extend [sign_extend zero_extend])
872
873 ;; This code iterator allows the two right shift instructions to be
874 ;; generated from the same template.
875 (define_code_iterator any_shiftrt [ashiftrt lshiftrt])
876
877 ;; This code iterator allows the three shift instructions to be generated
878 ;; from the same template.
879 (define_code_iterator any_shift [ashift ashiftrt lshiftrt])
880
881 ;; This code iterator allows unsigned and signed division to be generated
882 ;; from the same template.
883 (define_code_iterator any_div [div udiv])
884
885 ;; This code iterator allows unsigned and signed modulus to be generated
886 ;; from the same template.
887 (define_code_iterator any_mod [mod umod])
888
889 ;; This code iterator allows all native floating-point comparisons to be
890 ;; generated from the same template.
891 (define_code_iterator fcond [unordered uneq unlt unle eq lt le])
892
893 ;; This code iterator is used for comparisons that can be implemented
894 ;; by swapping the operands.
895 (define_code_iterator swapped_fcond [ge gt unge ungt])
896
897 ;; Equality operators.
898 (define_code_iterator equality_op [eq ne])
899
900 ;; These code iterators allow the signed and unsigned scc operations to use
901 ;; the same template.
902 (define_code_iterator any_gt [gt gtu])
903 (define_code_iterator any_ge [ge geu])
904 (define_code_iterator any_lt [lt ltu])
905 (define_code_iterator any_le [le leu])
906
907 (define_code_iterator any_return [return simple_return])
908
909 ;; <u> expands to an empty string when doing a signed operation and
910 ;; "u" when doing an unsigned operation.
911 (define_code_attr u [(sign_extend "") (zero_extend "u")
912 (div "") (udiv "u")
913 (mod "") (umod "u")
914 (gt "") (gtu "u")
915 (ge "") (geu "u")
916 (lt "") (ltu "u")
917 (le "") (leu "u")])
918
919 ;; <U> is like <u> except uppercase.
920 (define_code_attr U [(sign_extend "") (zero_extend "U")])
921
922 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
923 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
924
925 ;; <optab> expands to the name of the optab for a particular code.
926 (define_code_attr optab [(ashift "ashl")
927 (ashiftrt "ashr")
928 (lshiftrt "lshr")
929 (ior "ior")
930 (xor "xor")
931 (and "and")
932 (plus "add")
933 (minus "sub")
934 (return "return")
935 (simple_return "simple_return")])
936
937 ;; <insn> expands to the name of the insn that implements a particular code.
938 (define_code_attr insn [(ashift "sll")
939 (ashiftrt "sra")
940 (lshiftrt "srl")
941 (ior "or")
942 (xor "xor")
943 (and "and")
944 (plus "addu")
945 (minus "subu")])
946
947 ;; <immediate_insn> expands to the name of the insn that implements
948 ;; a particular code to operate on immediate values.
949 (define_code_attr immediate_insn [(ior "ori")
950 (xor "xori")
951 (and "andi")])
952
953 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
954 (define_code_attr fcond [(unordered "un")
955 (uneq "ueq")
956 (unlt "ult")
957 (unle "ule")
958 (eq "eq")
959 (lt "lt")
960 (le "le")])
961
962 ;; Similar, but for swapped conditions.
963 (define_code_attr swapped_fcond [(ge "le")
964 (gt "lt")
965 (unge "ule")
966 (ungt "ult")])
967
968 ;; The value of the bit when the branch is taken for branch_bit patterns.
969 ;; Comparison is always against zero so this depends on the operator.
970 (define_code_attr bbv [(eq "0") (ne "1")])
971
972 ;; This is the inverse value of bbv.
973 (define_code_attr bbinv [(eq "1") (ne "0")])
974 \f
975 ;; .........................
976 ;;
977 ;; Branch, call and jump delay slots
978 ;;
979 ;; .........................
980
981 (define_delay (and (eq_attr "type" "branch")
982 (not (match_test "TARGET_MIPS16"))
983 (eq_attr "branch_likely" "yes"))
984 [(eq_attr "can_delay" "yes")
985 (nil)
986 (eq_attr "can_delay" "yes")])
987
988 ;; Branches that don't have likely variants do not annul on false.
989 (define_delay (and (eq_attr "type" "branch")
990 (not (match_test "TARGET_MIPS16"))
991 (eq_attr "branch_likely" "no"))
992 [(eq_attr "can_delay" "yes")
993 (nil)
994 (nil)])
995
996 (define_delay (eq_attr "type" "jump")
997 [(eq_attr "can_delay" "yes")
998 (nil)
999 (nil)])
1000
1001 (define_delay (and (eq_attr "type" "call")
1002 (eq_attr "jal_macro" "no"))
1003 [(eq_attr "can_delay" "yes")
1004 (nil)
1005 (nil)])
1006 \f
1007 ;; Pipeline descriptions.
1008 ;;
1009 ;; generic.md provides a fallback for processors without a specific
1010 ;; pipeline description. It is derived from the old define_function_unit
1011 ;; version and uses the "alu" and "imuldiv" units declared below.
1012 ;;
1013 ;; Some of the processor-specific files are also derived from old
1014 ;; define_function_unit descriptions and simply override the parts of
1015 ;; generic.md that don't apply. The other processor-specific files
1016 ;; are self-contained.
1017 (define_automaton "alu,imuldiv")
1018
1019 (define_cpu_unit "alu" "alu")
1020 (define_cpu_unit "imuldiv" "imuldiv")
1021
1022 ;; Ghost instructions produce no real code and introduce no hazards.
1023 ;; They exist purely to express an effect on dataflow.
1024 (define_insn_reservation "ghost" 0
1025 (eq_attr "type" "ghost")
1026 "nothing")
1027
1028 (include "4k.md")
1029 (include "5k.md")
1030 (include "20kc.md")
1031 (include "24k.md")
1032 (include "74k.md")
1033 (include "3000.md")
1034 (include "4000.md")
1035 (include "4100.md")
1036 (include "4130.md")
1037 (include "4300.md")
1038 (include "4600.md")
1039 (include "5000.md")
1040 (include "5400.md")
1041 (include "5500.md")
1042 (include "6000.md")
1043 (include "7000.md")
1044 (include "9000.md")
1045 (include "10000.md")
1046 (include "loongson2ef.md")
1047 (include "loongson3a.md")
1048 (include "octeon.md")
1049 (include "sb1.md")
1050 (include "sr71k.md")
1051 (include "xlr.md")
1052 (include "xlp.md")
1053 (include "generic.md")
1054 \f
1055 ;;
1056 ;; ....................
1057 ;;
1058 ;; CONDITIONAL TRAPS
1059 ;;
1060 ;; ....................
1061 ;;
1062
1063 (define_insn "trap"
1064 [(trap_if (const_int 1) (const_int 0))]
1065 ""
1066 {
1067 if (ISA_HAS_COND_TRAP)
1068 return "teq\t$0,$0";
1069 else if (TARGET_MIPS16)
1070 return "break 0";
1071 else
1072 return "break";
1073 }
1074 [(set_attr "type" "trap")])
1075
1076 (define_expand "ctrap<mode>4"
1077 [(trap_if (match_operator 0 "comparison_operator"
1078 [(match_operand:GPR 1 "reg_or_0_operand")
1079 (match_operand:GPR 2 "arith_operand")])
1080 (match_operand 3 "const_0_operand"))]
1081 "ISA_HAS_COND_TRAP"
1082 {
1083 mips_expand_conditional_trap (operands[0]);
1084 DONE;
1085 })
1086
1087 (define_insn "*conditional_trap<mode>"
1088 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
1089 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
1090 (match_operand:GPR 2 "arith_operand" "dI")])
1091 (const_int 0))]
1092 "ISA_HAS_COND_TRAP"
1093 "t%C0\t%z1,%2"
1094 [(set_attr "type" "trap")])
1095 \f
1096 ;;
1097 ;; ....................
1098 ;;
1099 ;; ADDITION
1100 ;;
1101 ;; ....................
1102 ;;
1103
1104 (define_insn "add<mode>3"
1105 [(set (match_operand:ANYF 0 "register_operand" "=f")
1106 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1107 (match_operand:ANYF 2 "register_operand" "f")))]
1108 ""
1109 "add.<fmt>\t%0,%1,%2"
1110 [(set_attr "type" "fadd")
1111 (set_attr "mode" "<UNITMODE>")])
1112
1113 (define_expand "add<mode>3"
1114 [(set (match_operand:GPR 0 "register_operand")
1115 (plus:GPR (match_operand:GPR 1 "register_operand")
1116 (match_operand:GPR 2 "arith_operand")))]
1117 "")
1118
1119 (define_insn "*add<mode>3"
1120 [(set (match_operand:GPR 0 "register_operand" "=d,d")
1121 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
1122 (match_operand:GPR 2 "arith_operand" "d,Q")))]
1123 "!TARGET_MIPS16"
1124 "@
1125 <d>addu\t%0,%1,%2
1126 <d>addiu\t%0,%1,%2"
1127 [(set_attr "alu_type" "add")
1128 (set_attr "mode" "<MODE>")])
1129
1130 (define_insn "*add<mode>3_mips16"
1131 [(set (match_operand:GPR 0 "register_operand" "=ks,d,d,d,d")
1132 (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,0,d,d")
1133 (match_operand:GPR 2 "arith_operand" "Q,Q,Q,O,d")))]
1134 "TARGET_MIPS16"
1135 "@
1136 <d>addiu\t%0,%2
1137 <d>addiu\t%0,%1,%2
1138 <d>addiu\t%0,%2
1139 <d>addiu\t%0,%1,%2
1140 <d>addu\t%0,%1,%2"
1141 [(set_attr "alu_type" "add")
1142 (set_attr "mode" "<MODE>")
1143 (set_attr_alternative "length"
1144 [(if_then_else (match_operand 2 "m16_simm8_8")
1145 (const_int 4)
1146 (const_int 8))
1147 (if_then_else (match_operand 2 "m16_uimm<si8_di5>_4")
1148 (const_int 4)
1149 (const_int 8))
1150 (if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
1151 (const_int 4)
1152 (const_int 8))
1153 (if_then_else (match_operand 2 "m16_simm4_1")
1154 (const_int 4)
1155 (const_int 8))
1156 (const_int 4)])])
1157
1158 ;; On the mips16, we can sometimes split an add of a constant which is
1159 ;; a 4 byte instruction into two adds which are both 2 byte
1160 ;; instructions. There are two cases: one where we are adding a
1161 ;; constant plus a register to another register, and one where we are
1162 ;; simply adding a constant to a register.
1163
1164 (define_split
1165 [(set (match_operand:SI 0 "d_operand")
1166 (plus:SI (match_dup 0)
1167 (match_operand:SI 1 "const_int_operand")))]
1168 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1169 && ((INTVAL (operands[1]) > 0x7f
1170 && INTVAL (operands[1]) <= 0x7f + 0x7f)
1171 || (INTVAL (operands[1]) < - 0x80
1172 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
1173 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1174 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
1175 {
1176 HOST_WIDE_INT val = INTVAL (operands[1]);
1177
1178 if (val >= 0)
1179 {
1180 operands[1] = GEN_INT (0x7f);
1181 operands[2] = GEN_INT (val - 0x7f);
1182 }
1183 else
1184 {
1185 operands[1] = GEN_INT (- 0x80);
1186 operands[2] = GEN_INT (val + 0x80);
1187 }
1188 })
1189
1190 (define_split
1191 [(set (match_operand:SI 0 "d_operand")
1192 (plus:SI (match_operand:SI 1 "d_operand")
1193 (match_operand:SI 2 "const_int_operand")))]
1194 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
1195 && REGNO (operands[0]) != REGNO (operands[1])
1196 && ((INTVAL (operands[2]) > 0x7
1197 && INTVAL (operands[2]) <= 0x7 + 0x7f)
1198 || (INTVAL (operands[2]) < - 0x8
1199 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
1200 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
1201 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
1202 {
1203 HOST_WIDE_INT val = INTVAL (operands[2]);
1204
1205 if (val >= 0)
1206 {
1207 operands[2] = GEN_INT (0x7);
1208 operands[3] = GEN_INT (val - 0x7);
1209 }
1210 else
1211 {
1212 operands[2] = GEN_INT (- 0x8);
1213 operands[3] = GEN_INT (val + 0x8);
1214 }
1215 })
1216
1217 (define_split
1218 [(set (match_operand:DI 0 "d_operand")
1219 (plus:DI (match_dup 0)
1220 (match_operand:DI 1 "const_int_operand")))]
1221 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1222 && ((INTVAL (operands[1]) > 0xf
1223 && INTVAL (operands[1]) <= 0xf + 0xf)
1224 || (INTVAL (operands[1]) < - 0x10
1225 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1226 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1227 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1228 {
1229 HOST_WIDE_INT val = INTVAL (operands[1]);
1230
1231 if (val >= 0)
1232 {
1233 operands[1] = GEN_INT (0xf);
1234 operands[2] = GEN_INT (val - 0xf);
1235 }
1236 else
1237 {
1238 operands[1] = GEN_INT (- 0x10);
1239 operands[2] = GEN_INT (val + 0x10);
1240 }
1241 })
1242
1243 (define_split
1244 [(set (match_operand:DI 0 "d_operand")
1245 (plus:DI (match_operand:DI 1 "d_operand")
1246 (match_operand:DI 2 "const_int_operand")))]
1247 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1248 && REGNO (operands[0]) != REGNO (operands[1])
1249 && ((INTVAL (operands[2]) > 0x7
1250 && INTVAL (operands[2]) <= 0x7 + 0xf)
1251 || (INTVAL (operands[2]) < - 0x8
1252 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1253 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1254 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1255 {
1256 HOST_WIDE_INT val = INTVAL (operands[2]);
1257
1258 if (val >= 0)
1259 {
1260 operands[2] = GEN_INT (0x7);
1261 operands[3] = GEN_INT (val - 0x7);
1262 }
1263 else
1264 {
1265 operands[2] = GEN_INT (- 0x8);
1266 operands[3] = GEN_INT (val + 0x8);
1267 }
1268 })
1269
1270 (define_insn "*addsi3_extended"
1271 [(set (match_operand:DI 0 "register_operand" "=d,d")
1272 (sign_extend:DI
1273 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
1274 (match_operand:SI 2 "arith_operand" "d,Q"))))]
1275 "TARGET_64BIT && !TARGET_MIPS16"
1276 "@
1277 addu\t%0,%1,%2
1278 addiu\t%0,%1,%2"
1279 [(set_attr "alu_type" "add")
1280 (set_attr "mode" "SI")])
1281
1282 ;; Split this insn so that the addiu splitters can have a crack at it.
1283 ;; Use a conservative length estimate until the split.
1284 (define_insn_and_split "*addsi3_extended_mips16"
1285 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1286 (sign_extend:DI
1287 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1288 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1289 "TARGET_64BIT && TARGET_MIPS16"
1290 "#"
1291 "&& reload_completed"
1292 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
1293 { operands[3] = gen_lowpart (SImode, operands[0]); }
1294 [(set_attr "alu_type" "add")
1295 (set_attr "mode" "SI")
1296 (set_attr "extended_mips16" "yes")])
1297
1298 ;; Combiner patterns for unsigned byte-add.
1299
1300 (define_insn "*baddu_si"
1301 [(set (match_operand:SI 0 "register_operand" "=d")
1302 (zero_extend:SI
1303 (plus:QI (match_operand:QI 1 "register_operand" "d")
1304 (match_operand:QI 2 "register_operand" "d"))))]
1305 "ISA_HAS_BADDU"
1306 "baddu\\t%0,%1,%2"
1307 [(set_attr "alu_type" "add")])
1308
1309 (define_insn "*baddu_di<mode>"
1310 [(set (match_operand:GPR 0 "register_operand" "=d")
1311 (zero_extend:GPR
1312 (plus:QI (truncate:QI (match_operand:DI 1 "register_operand" "d"))
1313 (truncate:QI (match_operand:DI 2 "register_operand" "d")))))]
1314 "ISA_HAS_BADDU && TARGET_64BIT"
1315 "baddu\\t%0,%1,%2"
1316 [(set_attr "alu_type" "add")])
1317 \f
1318 ;;
1319 ;; ....................
1320 ;;
1321 ;; SUBTRACTION
1322 ;;
1323 ;; ....................
1324 ;;
1325
1326 (define_insn "sub<mode>3"
1327 [(set (match_operand:ANYF 0 "register_operand" "=f")
1328 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
1329 (match_operand:ANYF 2 "register_operand" "f")))]
1330 ""
1331 "sub.<fmt>\t%0,%1,%2"
1332 [(set_attr "type" "fadd")
1333 (set_attr "mode" "<UNITMODE>")])
1334
1335 (define_insn "sub<mode>3"
1336 [(set (match_operand:GPR 0 "register_operand" "=d")
1337 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
1338 (match_operand:GPR 2 "register_operand" "d")))]
1339 ""
1340 "<d>subu\t%0,%1,%2"
1341 [(set_attr "alu_type" "sub")
1342 (set_attr "mode" "<MODE>")])
1343
1344 (define_insn "*subsi3_extended"
1345 [(set (match_operand:DI 0 "register_operand" "=d")
1346 (sign_extend:DI
1347 (minus:SI (match_operand:SI 1 "register_operand" "d")
1348 (match_operand:SI 2 "register_operand" "d"))))]
1349 "TARGET_64BIT"
1350 "subu\t%0,%1,%2"
1351 [(set_attr "alu_type" "sub")
1352 (set_attr "mode" "DI")])
1353 \f
1354 ;;
1355 ;; ....................
1356 ;;
1357 ;; MULTIPLICATION
1358 ;;
1359 ;; ....................
1360 ;;
1361
1362 (define_expand "mul<mode>3"
1363 [(set (match_operand:SCALARF 0 "register_operand")
1364 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
1365 (match_operand:SCALARF 2 "register_operand")))]
1366 ""
1367 "")
1368
1369 (define_insn "*mul<mode>3"
1370 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1371 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1372 (match_operand:SCALARF 2 "register_operand" "f")))]
1373 "!TARGET_4300_MUL_FIX"
1374 "mul.<fmt>\t%0,%1,%2"
1375 [(set_attr "type" "fmul")
1376 (set_attr "mode" "<MODE>")])
1377
1378 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1379 ;; operands may corrupt immediately following multiplies. This is a
1380 ;; simple fix to insert NOPs.
1381
1382 (define_insn "*mul<mode>3_r4300"
1383 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1384 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1385 (match_operand:SCALARF 2 "register_operand" "f")))]
1386 "TARGET_4300_MUL_FIX"
1387 "mul.<fmt>\t%0,%1,%2\;nop"
1388 [(set_attr "type" "fmul")
1389 (set_attr "mode" "<MODE>")
1390 (set_attr "length" "8")])
1391
1392 (define_insn "mulv2sf3"
1393 [(set (match_operand:V2SF 0 "register_operand" "=f")
1394 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1395 (match_operand:V2SF 2 "register_operand" "f")))]
1396 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
1397 "mul.ps\t%0,%1,%2"
1398 [(set_attr "type" "fmul")
1399 (set_attr "mode" "SF")])
1400
1401 ;; The original R4000 has a cpu bug. If a double-word or a variable
1402 ;; shift executes while an integer multiplication is in progress, the
1403 ;; shift may give an incorrect result. Avoid this by keeping the mflo
1404 ;; with the mult on the R4000.
1405 ;;
1406 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1407 ;; (also valid for MIPS R4000MC processors):
1408 ;;
1409 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1410 ;; this errata description.
1411 ;; The following code sequence causes the R4000 to incorrectly
1412 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
1413 ;; instruction. If the dsra32 instruction is executed during an
1414 ;; integer multiply, the dsra32 will only shift by the amount in
1415 ;; specified in the instruction rather than the amount plus 32
1416 ;; bits.
1417 ;; instruction 1: mult rs,rt integer multiply
1418 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
1419 ;; right arithmetic + 32
1420 ;; Workaround: A dsra32 instruction placed after an integer
1421 ;; multiply should not be one of the 11 instructions after the
1422 ;; multiply instruction."
1423 ;;
1424 ;; and:
1425 ;;
1426 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1427 ;; the following description.
1428 ;; All extended shifts (shift by n+32) and variable shifts (32 and
1429 ;; 64-bit versions) may produce incorrect results under the
1430 ;; following conditions:
1431 ;; 1) An integer multiply is currently executing
1432 ;; 2) These types of shift instructions are executed immediately
1433 ;; following an integer divide instruction.
1434 ;; Workaround:
1435 ;; 1) Make sure no integer multiply is running wihen these
1436 ;; instruction are executed. If this cannot be predicted at
1437 ;; compile time, then insert a "mfhi" to R0 instruction
1438 ;; immediately after the integer multiply instruction. This
1439 ;; will cause the integer multiply to complete before the shift
1440 ;; is executed.
1441 ;; 2) Separate integer divide and these two classes of shift
1442 ;; instructions by another instruction or a noop."
1443 ;;
1444 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1445 ;; respectively.
1446
1447 (define_expand "mul<mode>3"
1448 [(set (match_operand:GPR 0 "register_operand")
1449 (mult:GPR (match_operand:GPR 1 "register_operand")
1450 (match_operand:GPR 2 "register_operand")))]
1451 ""
1452 {
1453 rtx lo;
1454
1455 if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
1456 emit_insn (gen_mul<mode>3_mul3_loongson (operands[0], operands[1],
1457 operands[2]));
1458 else if (ISA_HAS_<D>MUL3)
1459 emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2]));
1460 else if (TARGET_MIPS16)
1461 {
1462 lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
1463 emit_insn (gen_mul<mode>3_internal (lo, operands[1], operands[2]));
1464 emit_move_insn (operands[0], lo);
1465 }
1466 else if (TARGET_FIX_R4000)
1467 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1468 else
1469 emit_insn
1470 (gen_mul<mode>3_internal (operands[0], operands[1], operands[2]));
1471 DONE;
1472 })
1473
1474 (define_insn "mul<mode>3_mul3_loongson"
1475 [(set (match_operand:GPR 0 "register_operand" "=d")
1476 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1477 (match_operand:GPR 2 "register_operand" "d")))]
1478 "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
1479 {
1480 if (TARGET_LOONGSON_2EF)
1481 return "<d>multu.g\t%0,%1,%2";
1482 else
1483 return "gs<d>multu\t%0,%1,%2";
1484 }
1485 [(set_attr "type" "imul3nc")
1486 (set_attr "mode" "<MODE>")])
1487
1488 (define_insn "mul<mode>3_mul3"
1489 [(set (match_operand:GPR 0 "register_operand" "=d,l")
1490 (mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
1491 (match_operand:GPR 2 "register_operand" "d,d")))
1492 (clobber (match_scratch:GPR 3 "=l,X"))]
1493 "ISA_HAS_<D>MUL3"
1494 {
1495 if (which_alternative == 1)
1496 return "<d>mult\t%1,%2";
1497 if (<MODE>mode == SImode && TARGET_MIPS3900)
1498 return "mult\t%0,%1,%2";
1499 return "<d>mul\t%0,%1,%2";
1500 }
1501 [(set_attr "type" "imul3,imul")
1502 (set_attr "mode" "<MODE>")])
1503
1504 ;; If a register gets allocated to LO, and we spill to memory, the reload
1505 ;; will include a move from LO to a GPR. Merge it into the multiplication
1506 ;; if it can set the GPR directly.
1507 ;;
1508 ;; Operand 0: LO
1509 ;; Operand 1: GPR (1st multiplication operand)
1510 ;; Operand 2: GPR (2nd multiplication operand)
1511 ;; Operand 3: GPR (destination)
1512 (define_peephole2
1513 [(parallel
1514 [(set (match_operand:SI 0 "lo_operand")
1515 (mult:SI (match_operand:SI 1 "d_operand")
1516 (match_operand:SI 2 "d_operand")))
1517 (clobber (scratch:SI))])
1518 (set (match_operand:SI 3 "d_operand")
1519 (match_dup 0))]
1520 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1521 [(parallel
1522 [(set (match_dup 3)
1523 (mult:SI (match_dup 1)
1524 (match_dup 2)))
1525 (clobber (match_dup 0))])])
1526
1527 (define_insn "mul<mode>3_internal"
1528 [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
1529 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1530 (match_operand:GPR 2 "register_operand" "d")))]
1531 "!TARGET_FIX_R4000"
1532 "<d>mult\t%1,%2"
1533 [(set_attr "type" "imul")
1534 (set_attr "mode" "<MODE>")])
1535
1536 (define_insn "mul<mode>3_r4000"
1537 [(set (match_operand:GPR 0 "register_operand" "=d")
1538 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1539 (match_operand:GPR 2 "register_operand" "d")))
1540 (clobber (match_scratch:GPR 3 "=l"))]
1541 "TARGET_FIX_R4000"
1542 "<d>mult\t%1,%2\;mflo\t%0"
1543 [(set_attr "type" "imul")
1544 (set_attr "mode" "<MODE>")
1545 (set_attr "length" "8")])
1546
1547 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1548 ;; of "mult; mflo". They have the same latency, but the first form gives
1549 ;; us an extra cycle to compute the operands.
1550
1551 ;; Operand 0: LO
1552 ;; Operand 1: GPR (1st multiplication operand)
1553 ;; Operand 2: GPR (2nd multiplication operand)
1554 ;; Operand 3: GPR (destination)
1555 (define_peephole2
1556 [(set (match_operand:SI 0 "lo_operand")
1557 (mult:SI (match_operand:SI 1 "d_operand")
1558 (match_operand:SI 2 "d_operand")))
1559 (set (match_operand:SI 3 "d_operand")
1560 (match_dup 0))]
1561 "ISA_HAS_MACC && !ISA_HAS_MUL3"
1562 [(set (match_dup 0)
1563 (const_int 0))
1564 (parallel
1565 [(set (match_dup 0)
1566 (plus:SI (mult:SI (match_dup 1)
1567 (match_dup 2))
1568 (match_dup 0)))
1569 (set (match_dup 3)
1570 (plus:SI (mult:SI (match_dup 1)
1571 (match_dup 2))
1572 (match_dup 0)))])])
1573
1574 ;; Multiply-accumulate patterns
1575
1576 ;; This pattern is first matched by combine, which tries to use the
1577 ;; pattern wherever it can. We don't know until later whether it
1578 ;; is actually profitable to use MADD over a "MUL; ADDIU" sequence,
1579 ;; so we need to keep both options open.
1580 ;;
1581 ;; The second alternative has a "?" marker because it is generally
1582 ;; one instruction more costly than the first alternative. This "?"
1583 ;; marker is enough to convey the relative costs to the register
1584 ;; allocator.
1585 ;;
1586 ;; However, reload counts reloads of operands 4 and 5 in the same way as
1587 ;; reloads of the other operands, even though operands 4 and 5 need no
1588 ;; copy instructions. Reload therefore thinks that the second alternative
1589 ;; is two reloads more costly than the first. We add "*?*?" to the first
1590 ;; alternative as a counterweight.
1591 (define_insn "*mul_acc_si"
1592 [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
1593 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1594 (match_operand:SI 2 "register_operand" "d,d"))
1595 (match_operand:SI 3 "register_operand" "0,d")))
1596 (clobber (match_scratch:SI 4 "=X,l"))
1597 (clobber (match_scratch:SI 5 "=X,&d"))]
1598 "GENERATE_MADD_MSUB && !TARGET_MIPS16"
1599 "@
1600 madd\t%1,%2
1601 #"
1602 [(set_attr "type" "imadd")
1603 (set_attr "accum_in" "3")
1604 (set_attr "mode" "SI")
1605 (set_attr "length" "4,8")])
1606
1607 ;; The same idea applies here. The middle alternative needs one less
1608 ;; clobber than the final alternative, so we add "*?" as a counterweight.
1609 (define_insn "*mul_acc_si_r3900"
1610 [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?")
1611 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1612 (match_operand:SI 2 "register_operand" "d,d,d"))
1613 (match_operand:SI 3 "register_operand" "0,l,d")))
1614 (clobber (match_scratch:SI 4 "=X,3,l"))
1615 (clobber (match_scratch:SI 5 "=X,X,&d"))]
1616 "TARGET_MIPS3900 && !TARGET_MIPS16"
1617 "@
1618 madd\t%1,%2
1619 madd\t%0,%1,%2
1620 #"
1621 [(set_attr "type" "imadd")
1622 (set_attr "accum_in" "3")
1623 (set_attr "mode" "SI")
1624 (set_attr "length" "4,4,8")])
1625
1626 ;; Split *mul_acc_si if both the source and destination accumulator
1627 ;; values are GPRs.
1628 (define_split
1629 [(set (match_operand:SI 0 "d_operand")
1630 (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
1631 (match_operand:SI 2 "d_operand"))
1632 (match_operand:SI 3 "d_operand")))
1633 (clobber (match_operand:SI 4 "lo_operand"))
1634 (clobber (match_operand:SI 5 "d_operand"))]
1635 "reload_completed"
1636 [(parallel [(set (match_dup 5)
1637 (mult:SI (match_dup 1) (match_dup 2)))
1638 (clobber (match_dup 4))])
1639 (set (match_dup 0) (plus:SI (match_dup 5) (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 "=X,3"))]
1648 "ISA_HAS_MACC"
1649 {
1650 if (which_alternative == 1)
1651 return "macc\t%0,%1,%2";
1652 else if (TARGET_MIPS5500)
1653 return "madd\t%1,%2";
1654 else
1655 /* The VR4130 assumes that there is a two-cycle latency between a macc
1656 that "writes" to $0 and an instruction that reads from it. We avoid
1657 this by assigning to $1 instead. */
1658 return "%[macc\t%@,%1,%2%]";
1659 }
1660 [(set_attr "type" "imadd")
1661 (set_attr "accum_in" "3")
1662 (set_attr "mode" "SI")])
1663
1664 (define_insn "*msac"
1665 [(set (match_operand:SI 0 "register_operand" "=l,d")
1666 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1667 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1668 (match_operand:SI 3 "register_operand" "d,d"))))
1669 (clobber (match_scratch:SI 4 "=X,1"))]
1670 "ISA_HAS_MSAC"
1671 {
1672 if (which_alternative == 1)
1673 return "msac\t%0,%2,%3";
1674 else if (TARGET_MIPS5500)
1675 return "msub\t%2,%3";
1676 else
1677 return "msac\t$0,%2,%3";
1678 }
1679 [(set_attr "type" "imadd")
1680 (set_attr "accum_in" "1")
1681 (set_attr "mode" "SI")])
1682
1683 ;; An msac-like instruction implemented using negation and a macc.
1684 (define_insn_and_split "*msac_using_macc"
1685 [(set (match_operand:SI 0 "register_operand" "=l,d")
1686 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1687 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1688 (match_operand:SI 3 "register_operand" "d,d"))))
1689 (clobber (match_scratch:SI 4 "=X,1"))
1690 (clobber (match_scratch:SI 5 "=d,d"))]
1691 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1692 "#"
1693 "&& reload_completed"
1694 [(set (match_dup 5)
1695 (neg:SI (match_dup 3)))
1696 (parallel
1697 [(set (match_dup 0)
1698 (plus:SI (mult:SI (match_dup 2)
1699 (match_dup 5))
1700 (match_dup 1)))
1701 (clobber (match_dup 4))])]
1702 ""
1703 [(set_attr "type" "imadd")
1704 (set_attr "accum_in" "1")
1705 (set_attr "length" "8")])
1706
1707 ;; Patterns generated by the define_peephole2 below.
1708
1709 (define_insn "*macc2"
1710 [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1711 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1712 (match_operand:SI 2 "register_operand" "d"))
1713 (match_dup 0)))
1714 (set (match_operand:SI 3 "register_operand" "=d")
1715 (plus:SI (mult:SI (match_dup 1)
1716 (match_dup 2))
1717 (match_dup 0)))]
1718 "ISA_HAS_MACC && reload_completed"
1719 "macc\t%3,%1,%2"
1720 [(set_attr "type" "imadd")
1721 (set_attr "accum_in" "0")
1722 (set_attr "mode" "SI")])
1723
1724 (define_insn "*msac2"
1725 [(set (match_operand:SI 0 "muldiv_target_operand" "=l")
1726 (minus:SI (match_dup 0)
1727 (mult:SI (match_operand:SI 1 "register_operand" "d")
1728 (match_operand:SI 2 "register_operand" "d"))))
1729 (set (match_operand:SI 3 "register_operand" "=d")
1730 (minus:SI (match_dup 0)
1731 (mult:SI (match_dup 1)
1732 (match_dup 2))))]
1733 "ISA_HAS_MSAC && reload_completed"
1734 "msac\t%3,%1,%2"
1735 [(set_attr "type" "imadd")
1736 (set_attr "accum_in" "0")
1737 (set_attr "mode" "SI")])
1738
1739 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1740 ;; Similarly msac.
1741 ;;
1742 ;; Operand 0: LO
1743 ;; Operand 1: macc/msac
1744 ;; Operand 2: GPR (destination)
1745 (define_peephole2
1746 [(parallel
1747 [(set (match_operand:SI 0 "lo_operand")
1748 (match_operand:SI 1 "macc_msac_operand"))
1749 (clobber (scratch:SI))])
1750 (set (match_operand:SI 2 "d_operand")
1751 (match_dup 0))]
1752 ""
1753 [(parallel [(set (match_dup 0)
1754 (match_dup 1))
1755 (set (match_dup 2)
1756 (match_dup 1))])])
1757
1758 ;; When we have a three-address multiplication instruction, it should
1759 ;; be faster to do a separate multiply and add, rather than moving
1760 ;; something into LO in order to use a macc instruction.
1761 ;;
1762 ;; This peephole needs a scratch register to cater for the case when one
1763 ;; of the multiplication operands is the same as the destination.
1764 ;;
1765 ;; Operand 0: GPR (scratch)
1766 ;; Operand 1: LO
1767 ;; Operand 2: GPR (addend)
1768 ;; Operand 3: GPR (destination)
1769 ;; Operand 4: macc/msac
1770 ;; Operand 5: new multiplication
1771 ;; Operand 6: new addition/subtraction
1772 (define_peephole2
1773 [(match_scratch:SI 0 "d")
1774 (set (match_operand:SI 1 "lo_operand")
1775 (match_operand:SI 2 "d_operand"))
1776 (match_dup 0)
1777 (parallel
1778 [(set (match_operand:SI 3 "d_operand")
1779 (match_operand:SI 4 "macc_msac_operand"))
1780 (clobber (match_dup 1))])]
1781 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])"
1782 [(parallel [(set (match_dup 0)
1783 (match_dup 5))
1784 (clobber (match_dup 1))])
1785 (set (match_dup 3)
1786 (match_dup 6))]
1787 {
1788 operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1789 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1790 operands[2], operands[0]);
1791 })
1792
1793 ;; Same as above, except LO is the initial target of the macc.
1794 ;;
1795 ;; Operand 0: GPR (scratch)
1796 ;; Operand 1: LO
1797 ;; Operand 2: GPR (addend)
1798 ;; Operand 3: macc/msac
1799 ;; Operand 4: GPR (destination)
1800 ;; Operand 5: new multiplication
1801 ;; Operand 6: new addition/subtraction
1802 (define_peephole2
1803 [(match_scratch:SI 0 "d")
1804 (set (match_operand:SI 1 "lo_operand")
1805 (match_operand:SI 2 "d_operand"))
1806 (match_dup 0)
1807 (parallel
1808 [(set (match_dup 1)
1809 (match_operand:SI 3 "macc_msac_operand"))
1810 (clobber (scratch:SI))])
1811 (match_dup 0)
1812 (set (match_operand:SI 4 "d_operand")
1813 (match_dup 1))]
1814 "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1815 [(parallel [(set (match_dup 0)
1816 (match_dup 5))
1817 (clobber (match_dup 1))])
1818 (set (match_dup 4)
1819 (match_dup 6))]
1820 {
1821 operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1);
1822 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
1823 operands[2], operands[0]);
1824 })
1825
1826 ;; See the comment above *mul_add_si for details.
1827 (define_insn "*mul_sub_si"
1828 [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
1829 (minus:SI (match_operand:SI 1 "register_operand" "0,d")
1830 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1831 (match_operand:SI 3 "register_operand" "d,d"))))
1832 (clobber (match_scratch:SI 4 "=X,l"))
1833 (clobber (match_scratch:SI 5 "=X,&d"))]
1834 "GENERATE_MADD_MSUB"
1835 "@
1836 msub\t%2,%3
1837 #"
1838 [(set_attr "type" "imadd")
1839 (set_attr "accum_in" "1")
1840 (set_attr "mode" "SI")
1841 (set_attr "length" "4,8")])
1842
1843 ;; Split *mul_sub_si if both the source and destination accumulator
1844 ;; values are GPRs.
1845 (define_split
1846 [(set (match_operand:SI 0 "d_operand")
1847 (minus:SI (match_operand:SI 1 "d_operand")
1848 (mult:SI (match_operand:SI 2 "d_operand")
1849 (match_operand:SI 3 "d_operand"))))
1850 (clobber (match_operand:SI 4 "lo_operand"))
1851 (clobber (match_operand:SI 5 "d_operand"))]
1852 "reload_completed"
1853 [(parallel [(set (match_dup 5)
1854 (mult:SI (match_dup 2) (match_dup 3)))
1855 (clobber (match_dup 4))])
1856 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
1857 "")
1858
1859 (define_insn "*muls"
1860 [(set (match_operand:SI 0 "register_operand" "=l,d")
1861 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1862 (match_operand:SI 2 "register_operand" "d,d"))))
1863 (clobber (match_scratch:SI 3 "=X,l"))]
1864 "ISA_HAS_MULS"
1865 "@
1866 muls\t$0,%1,%2
1867 muls\t%0,%1,%2"
1868 [(set_attr "type" "imul,imul3")
1869 (set_attr "mode" "SI")])
1870
1871 (define_expand "<u>mulsidi3"
1872 [(set (match_operand:DI 0 "register_operand")
1873 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1874 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1875 "mips_mulsidi3_gen_fn (<CODE>) != NULL"
1876 {
1877 mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>);
1878 emit_insn (fn (operands[0], operands[1], operands[2]));
1879 DONE;
1880 })
1881
1882 (define_expand "<u>mulsidi3_32bit_mips16"
1883 [(set (match_operand:DI 0 "register_operand")
1884 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1885 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1886 "!TARGET_64BIT && TARGET_MIPS16"
1887 {
1888 rtx hilo;
1889
1890 hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
1891 emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
1892 emit_move_insn (operands[0], hilo);
1893 DONE;
1894 })
1895
1896 ;; As well as being named patterns, these instructions are used by the
1897 ;; __builtin_mips_mult<u>() functions. We must always make those functions
1898 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
1899 (define_insn "<u>mulsidi3_32bit"
1900 [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
1901 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1902 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1903 "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP)"
1904 {
1905 if (ISA_HAS_DSP_MULT)
1906 return "mult<u>\t%q0,%1,%2";
1907 else
1908 return "mult<u>\t%1,%2";
1909 }
1910 [(set_attr "type" "imul")
1911 (set_attr "mode" "SI")])
1912
1913 (define_insn "<u>mulsidi3_32bit_r4000"
1914 [(set (match_operand:DI 0 "register_operand" "=d")
1915 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1916 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1917 (clobber (match_scratch:DI 3 "=x"))]
1918 "!TARGET_64BIT && TARGET_FIX_R4000 && !ISA_HAS_DSP"
1919 "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
1920 [(set_attr "type" "imul")
1921 (set_attr "mode" "SI")
1922 (set_attr "length" "12")])
1923
1924 (define_insn_and_split "<u>mulsidi3_64bit"
1925 [(set (match_operand:DI 0 "register_operand" "=d")
1926 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1927 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1928 (clobber (match_scratch:TI 3 "=x"))
1929 (clobber (match_scratch:DI 4 "=d"))]
1930 "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3 && !TARGET_MIPS16"
1931 "#"
1932 "&& reload_completed"
1933 [(const_int 0)]
1934 {
1935 emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
1936 operands[2], operands[4]));
1937 DONE;
1938 }
1939 [(set_attr "type" "imul")
1940 (set_attr "mode" "SI")
1941 (set (attr "length")
1942 (if_then_else (match_test "ISA_HAS_EXT_INS")
1943 (const_int 16)
1944 (const_int 28)))])
1945
1946 (define_expand "<u>mulsidi3_64bit_mips16"
1947 [(set (match_operand:DI 0 "register_operand")
1948 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1949 (any_extend:DI (match_operand:SI 2 "register_operand"))))]
1950 "TARGET_64BIT && TARGET_MIPS16"
1951 {
1952 emit_insn (gen_<u>mulsidi3_64bit_split (operands[0], operands[1],
1953 operands[2], gen_reg_rtx (DImode)));
1954 DONE;
1955 })
1956
1957 (define_expand "<u>mulsidi3_64bit_split"
1958 [(set (match_operand:DI 0 "register_operand")
1959 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1960 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1961 (clobber (match_operand:DI 3 "register_operand"))]
1962 ""
1963 {
1964 rtx hilo;
1965
1966 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
1967 emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
1968
1969 emit_move_insn (operands[0], gen_rtx_REG (DImode, LO_REGNUM));
1970 emit_insn (gen_mfhidi_ti (operands[3], hilo));
1971
1972 if (ISA_HAS_EXT_INS)
1973 emit_insn (gen_insvdi (operands[0], GEN_INT (32), GEN_INT (32),
1974 operands[3]));
1975 else
1976 {
1977 /* Zero-extend the low part. */
1978 mips_emit_binary (ASHIFT, operands[0], operands[0], GEN_INT (32));
1979 mips_emit_binary (LSHIFTRT, operands[0], operands[0], GEN_INT (32));
1980
1981 /* Shift the high part into place. */
1982 mips_emit_binary (ASHIFT, operands[3], operands[3], GEN_INT (32));
1983
1984 /* OR the two halves together. */
1985 mips_emit_binary (IOR, operands[0], operands[0], operands[3]);
1986 }
1987 DONE;
1988 })
1989
1990 (define_insn "<u>mulsidi3_64bit_hilo"
1991 [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
1992 (unspec:TI
1993 [(mult:DI
1994 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1995 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))]
1996 UNSPEC_SET_HILO))]
1997 "TARGET_64BIT && !TARGET_FIX_R4000"
1998 "mult<u>\t%1,%2"
1999 [(set_attr "type" "imul")
2000 (set_attr "mode" "SI")])
2001
2002 ;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn.
2003 (define_insn "mulsidi3_64bit_dmul"
2004 [(set (match_operand:DI 0 "register_operand" "=d")
2005 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2006 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2007 (clobber (match_scratch:DI 3 "=l"))]
2008 "TARGET_64BIT && ISA_HAS_DMUL3"
2009 "dmul\t%0,%1,%2"
2010 [(set_attr "type" "imul3")
2011 (set_attr "mode" "DI")])
2012
2013 ;; Widening multiply with negation.
2014 (define_insn "*muls<u>_di"
2015 [(set (match_operand:DI 0 "muldiv_target_operand" "=x")
2016 (neg:DI
2017 (mult:DI
2018 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2019 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2020 "!TARGET_64BIT && ISA_HAS_MULS"
2021 "muls<u>\t$0,%1,%2"
2022 [(set_attr "type" "imul")
2023 (set_attr "mode" "SI")])
2024
2025 ;; As well as being named patterns, these instructions are used by the
2026 ;; __builtin_mips_msub<u>() functions. We must always make those functions
2027 ;; available if !TARGET_64BIT && ISA_HAS_DSP.
2028 ;;
2029 ;; This leads to a slight inconsistency. We honor any tuning overrides
2030 ;; in GENERATE_MADD_MSUB for -mno-dsp, but always ignore them for -mdsp,
2031 ;; even if !ISA_HAS_DSP_MULT.
2032 (define_insn "<u>msubsidi4"
2033 [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2034 (minus:DI
2035 (match_operand:DI 3 "muldiv_target_operand" "0")
2036 (mult:DI
2037 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2038 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2039 "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)"
2040 {
2041 if (ISA_HAS_DSP_MULT)
2042 return "msub<u>\t%q0,%1,%2";
2043 else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
2044 return "msub<u>\t%1,%2";
2045 else
2046 return "msac<u>\t$0,%1,%2";
2047 }
2048 [(set_attr "type" "imadd")
2049 (set_attr "accum_in" "3")
2050 (set_attr "mode" "SI")])
2051
2052 ;; _highpart patterns
2053
2054 (define_expand "<su>mulsi3_highpart"
2055 [(set (match_operand:SI 0 "register_operand")
2056 (truncate:SI
2057 (lshiftrt:DI
2058 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2059 (any_extend:DI (match_operand:SI 2 "register_operand")))
2060 (const_int 32))))]
2061 ""
2062 {
2063 if (ISA_HAS_MULHI)
2064 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
2065 operands[1],
2066 operands[2]));
2067 else if (TARGET_MIPS16)
2068 emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2069 operands[2]));
2070 else
2071 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
2072 operands[2]));
2073 DONE;
2074 })
2075
2076 (define_insn_and_split "<su>mulsi3_highpart_internal"
2077 [(set (match_operand:SI 0 "register_operand" "=d")
2078 (truncate:SI
2079 (lshiftrt:DI
2080 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2081 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2082 (const_int 32))))
2083 (clobber (match_scratch:SI 3 "=l"))]
2084 "!ISA_HAS_MULHI && !TARGET_MIPS16"
2085 { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2086 "&& reload_completed && !TARGET_FIX_R4000"
2087 [(const_int 0)]
2088 {
2089 emit_insn (gen_<su>mulsi3_highpart_split (operands[0], operands[1],
2090 operands[2]));
2091 DONE;
2092 }
2093 [(set_attr "type" "imul")
2094 (set_attr "mode" "SI")
2095 (set_attr "length" "8")])
2096
2097 (define_expand "<su>mulsi3_highpart_split"
2098 [(set (match_operand:SI 0 "register_operand")
2099 (truncate:SI
2100 (lshiftrt:DI
2101 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
2102 (any_extend:DI (match_operand:SI 2 "register_operand")))
2103 (const_int 32))))]
2104 ""
2105 {
2106 rtx hilo;
2107
2108 if (TARGET_64BIT)
2109 {
2110 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2111 emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2]));
2112 emit_insn (gen_mfhisi_ti (operands[0], hilo));
2113 }
2114 else
2115 {
2116 hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2117 emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2]));
2118 emit_insn (gen_mfhisi_di (operands[0], hilo));
2119 }
2120 DONE;
2121 })
2122
2123 (define_insn "<su>mulsi3_highpart_mulhi_internal"
2124 [(set (match_operand:SI 0 "register_operand" "=d")
2125 (truncate:SI
2126 (lshiftrt:DI
2127 (mult:DI
2128 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2129 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2130 (const_int 32))))
2131 (clobber (match_scratch:SI 3 "=l"))]
2132 "ISA_HAS_MULHI"
2133 "mulhi<u>\t%0,%1,%2"
2134 [(set_attr "type" "imul3")
2135 (set_attr "mode" "SI")])
2136
2137 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
2138 [(set (match_operand:SI 0 "register_operand" "=d")
2139 (truncate:SI
2140 (lshiftrt:DI
2141 (neg:DI
2142 (mult:DI
2143 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2144 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2145 (const_int 32))))
2146 (clobber (match_scratch:SI 3 "=l"))]
2147 "ISA_HAS_MULHI"
2148 "mulshi<u>\t%0,%1,%2"
2149 [(set_attr "type" "imul3")
2150 (set_attr "mode" "SI")])
2151
2152 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
2153 ;; errata MD(0), which says that dmultu does not always produce the
2154 ;; correct result.
2155 (define_expand "<su>muldi3_highpart"
2156 [(set (match_operand:DI 0 "register_operand")
2157 (truncate:DI
2158 (lshiftrt:TI
2159 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2160 (any_extend:TI (match_operand:DI 2 "register_operand")))
2161 (const_int 64))))]
2162 "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2163 {
2164 if (TARGET_MIPS16)
2165 emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2166 operands[2]));
2167 else
2168 emit_insn (gen_<su>muldi3_highpart_internal (operands[0], operands[1],
2169 operands[2]));
2170 DONE;
2171 })
2172
2173 (define_insn_and_split "<su>muldi3_highpart_internal"
2174 [(set (match_operand:DI 0 "register_operand" "=d")
2175 (truncate:DI
2176 (lshiftrt:TI
2177 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2178 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
2179 (const_int 64))))
2180 (clobber (match_scratch:DI 3 "=l"))]
2181 "TARGET_64BIT
2182 && !TARGET_MIPS16
2183 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2184 { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
2185 "&& reload_completed && !TARGET_FIX_R4000"
2186 [(const_int 0)]
2187 {
2188 emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
2189 operands[2]));
2190 DONE;
2191 }
2192 [(set_attr "type" "imul")
2193 (set_attr "mode" "DI")
2194 (set_attr "length" "8")])
2195
2196 (define_expand "<su>muldi3_highpart_split"
2197 [(set (match_operand:DI 0 "register_operand")
2198 (truncate:DI
2199 (lshiftrt:TI
2200 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2201 (any_extend:TI (match_operand:DI 2 "register_operand")))
2202 (const_int 64))))]
2203 ""
2204 {
2205 rtx hilo;
2206
2207 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2208 emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2209 emit_insn (gen_mfhidi_ti (operands[0], hilo));
2210 DONE;
2211 })
2212
2213 (define_expand "<u>mulditi3"
2214 [(set (match_operand:TI 0 "register_operand")
2215 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
2216 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
2217 "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2218 {
2219 rtx hilo;
2220
2221 if (TARGET_MIPS16)
2222 {
2223 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2224 emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2]));
2225 emit_move_insn (operands[0], hilo);
2226 }
2227 else if (TARGET_FIX_R4000)
2228 emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2]));
2229 else
2230 emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1],
2231 operands[2]));
2232 DONE;
2233 })
2234
2235 (define_insn "<u>mulditi3_internal"
2236 [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
2237 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2238 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
2239 "TARGET_64BIT
2240 && !TARGET_FIX_R4000
2241 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2242 "dmult<u>\t%1,%2"
2243 [(set_attr "type" "imul")
2244 (set_attr "mode" "DI")])
2245
2246 (define_insn "<u>mulditi3_r4000"
2247 [(set (match_operand:TI 0 "register_operand" "=d")
2248 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
2249 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
2250 (clobber (match_scratch:TI 3 "=x"))]
2251 "TARGET_64BIT
2252 && TARGET_FIX_R4000
2253 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
2254 "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
2255 [(set_attr "type" "imul")
2256 (set_attr "mode" "DI")
2257 (set_attr "length" "12")])
2258
2259 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
2260 ;; instruction. The HI/LO registers are used as a 64-bit accumulator.
2261
2262 (define_insn "madsi"
2263 [(set (match_operand:SI 0 "register_operand" "+l")
2264 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2265 (match_operand:SI 2 "register_operand" "d"))
2266 (match_dup 0)))]
2267 "TARGET_MAD"
2268 "mad\t%1,%2"
2269 [(set_attr "type" "imadd")
2270 (set_attr "accum_in" "0")
2271 (set_attr "mode" "SI")])
2272
2273 ;; See the comment above <u>msubsidi4 for the relationship between
2274 ;; ISA_HAS_DSP and ISA_HAS_DSP_MULT.
2275 (define_insn "<u>maddsidi4"
2276 [(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
2277 (plus:DI
2278 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
2279 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
2280 (match_operand:DI 3 "muldiv_target_operand" "0")))]
2281 "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP)
2282 && !TARGET_64BIT"
2283 {
2284 if (TARGET_MAD)
2285 return "mad<u>\t%1,%2";
2286 else if (ISA_HAS_DSP_MULT)
2287 return "madd<u>\t%q0,%1,%2";
2288 else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
2289 return "madd<u>\t%1,%2";
2290 else
2291 /* See comment in *macc. */
2292 return "%[macc<u>\t%@,%1,%2%]";
2293 }
2294 [(set_attr "type" "imadd")
2295 (set_attr "accum_in" "3")
2296 (set_attr "mode" "SI")])
2297
2298 ;; Floating point multiply accumulate instructions.
2299
2300 (define_insn "*madd4<mode>"
2301 [(set (match_operand:ANYF 0 "register_operand" "=f")
2302 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2303 (match_operand:ANYF 2 "register_operand" "f"))
2304 (match_operand:ANYF 3 "register_operand" "f")))]
2305 "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2306 "madd.<fmt>\t%0,%3,%1,%2"
2307 [(set_attr "type" "fmadd")
2308 (set_attr "accum_in" "3")
2309 (set_attr "mode" "<UNITMODE>")])
2310
2311 (define_insn "*madd3<mode>"
2312 [(set (match_operand:ANYF 0 "register_operand" "=f")
2313 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2314 (match_operand:ANYF 2 "register_operand" "f"))
2315 (match_operand:ANYF 3 "register_operand" "0")))]
2316 "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2317 "madd.<fmt>\t%0,%1,%2"
2318 [(set_attr "type" "fmadd")
2319 (set_attr "accum_in" "3")
2320 (set_attr "mode" "<UNITMODE>")])
2321
2322 (define_insn "*msub4<mode>"
2323 [(set (match_operand:ANYF 0 "register_operand" "=f")
2324 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2325 (match_operand:ANYF 2 "register_operand" "f"))
2326 (match_operand:ANYF 3 "register_operand" "f")))]
2327 "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD"
2328 "msub.<fmt>\t%0,%3,%1,%2"
2329 [(set_attr "type" "fmadd")
2330 (set_attr "accum_in" "3")
2331 (set_attr "mode" "<UNITMODE>")])
2332
2333 (define_insn "*msub3<mode>"
2334 [(set (match_operand:ANYF 0 "register_operand" "=f")
2335 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2336 (match_operand:ANYF 2 "register_operand" "f"))
2337 (match_operand:ANYF 3 "register_operand" "0")))]
2338 "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD"
2339 "msub.<fmt>\t%0,%1,%2"
2340 [(set_attr "type" "fmadd")
2341 (set_attr "accum_in" "3")
2342 (set_attr "mode" "<UNITMODE>")])
2343
2344 (define_insn "*nmadd4<mode>"
2345 [(set (match_operand:ANYF 0 "register_operand" "=f")
2346 (neg:ANYF (plus:ANYF
2347 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2348 (match_operand:ANYF 2 "register_operand" "f"))
2349 (match_operand:ANYF 3 "register_operand" "f"))))]
2350 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
2351 && TARGET_FUSED_MADD
2352 && HONOR_SIGNED_ZEROS (<MODE>mode)
2353 && !HONOR_NANS (<MODE>mode)"
2354 "nmadd.<fmt>\t%0,%3,%1,%2"
2355 [(set_attr "type" "fmadd")
2356 (set_attr "accum_in" "3")
2357 (set_attr "mode" "<UNITMODE>")])
2358
2359 (define_insn "*nmadd3<mode>"
2360 [(set (match_operand:ANYF 0 "register_operand" "=f")
2361 (neg:ANYF (plus:ANYF
2362 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
2363 (match_operand:ANYF 2 "register_operand" "f"))
2364 (match_operand:ANYF 3 "register_operand" "0"))))]
2365 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
2366 && TARGET_FUSED_MADD
2367 && HONOR_SIGNED_ZEROS (<MODE>mode)
2368 && !HONOR_NANS (<MODE>mode)"
2369 "nmadd.<fmt>\t%0,%1,%2"
2370 [(set_attr "type" "fmadd")
2371 (set_attr "accum_in" "3")
2372 (set_attr "mode" "<UNITMODE>")])
2373
2374 (define_insn "*nmadd4<mode>_fastmath"
2375 [(set (match_operand:ANYF 0 "register_operand" "=f")
2376 (minus:ANYF
2377 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2378 (match_operand:ANYF 2 "register_operand" "f"))
2379 (match_operand:ANYF 3 "register_operand" "f")))]
2380 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
2381 && TARGET_FUSED_MADD
2382 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2383 && !HONOR_NANS (<MODE>mode)"
2384 "nmadd.<fmt>\t%0,%3,%1,%2"
2385 [(set_attr "type" "fmadd")
2386 (set_attr "accum_in" "3")
2387 (set_attr "mode" "<UNITMODE>")])
2388
2389 (define_insn "*nmadd3<mode>_fastmath"
2390 [(set (match_operand:ANYF 0 "register_operand" "=f")
2391 (minus:ANYF
2392 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
2393 (match_operand:ANYF 2 "register_operand" "f"))
2394 (match_operand:ANYF 3 "register_operand" "0")))]
2395 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
2396 && TARGET_FUSED_MADD
2397 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2398 && !HONOR_NANS (<MODE>mode)"
2399 "nmadd.<fmt>\t%0,%1,%2"
2400 [(set_attr "type" "fmadd")
2401 (set_attr "accum_in" "3")
2402 (set_attr "mode" "<UNITMODE>")])
2403
2404 (define_insn "*nmsub4<mode>"
2405 [(set (match_operand:ANYF 0 "register_operand" "=f")
2406 (neg:ANYF (minus:ANYF
2407 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2408 (match_operand:ANYF 3 "register_operand" "f"))
2409 (match_operand:ANYF 1 "register_operand" "f"))))]
2410 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
2411 && TARGET_FUSED_MADD
2412 && HONOR_SIGNED_ZEROS (<MODE>mode)
2413 && !HONOR_NANS (<MODE>mode)"
2414 "nmsub.<fmt>\t%0,%1,%2,%3"
2415 [(set_attr "type" "fmadd")
2416 (set_attr "accum_in" "1")
2417 (set_attr "mode" "<UNITMODE>")])
2418
2419 (define_insn "*nmsub3<mode>"
2420 [(set (match_operand:ANYF 0 "register_operand" "=f")
2421 (neg:ANYF (minus:ANYF
2422 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2423 (match_operand:ANYF 3 "register_operand" "f"))
2424 (match_operand:ANYF 1 "register_operand" "0"))))]
2425 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
2426 && TARGET_FUSED_MADD
2427 && HONOR_SIGNED_ZEROS (<MODE>mode)
2428 && !HONOR_NANS (<MODE>mode)"
2429 "nmsub.<fmt>\t%0,%1,%2"
2430 [(set_attr "type" "fmadd")
2431 (set_attr "accum_in" "1")
2432 (set_attr "mode" "<UNITMODE>")])
2433
2434 (define_insn "*nmsub4<mode>_fastmath"
2435 [(set (match_operand:ANYF 0 "register_operand" "=f")
2436 (minus:ANYF
2437 (match_operand:ANYF 1 "register_operand" "f")
2438 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2439 (match_operand:ANYF 3 "register_operand" "f"))))]
2440 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)
2441 && TARGET_FUSED_MADD
2442 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2443 && !HONOR_NANS (<MODE>mode)"
2444 "nmsub.<fmt>\t%0,%1,%2,%3"
2445 [(set_attr "type" "fmadd")
2446 (set_attr "accum_in" "1")
2447 (set_attr "mode" "<UNITMODE>")])
2448
2449 (define_insn "*nmsub3<mode>_fastmath"
2450 [(set (match_operand:ANYF 0 "register_operand" "=f")
2451 (minus:ANYF
2452 (match_operand:ANYF 1 "register_operand" "f")
2453 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
2454 (match_operand:ANYF 3 "register_operand" "0"))))]
2455 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode)
2456 && TARGET_FUSED_MADD
2457 && !HONOR_SIGNED_ZEROS (<MODE>mode)
2458 && !HONOR_NANS (<MODE>mode)"
2459 "nmsub.<fmt>\t%0,%1,%2"
2460 [(set_attr "type" "fmadd")
2461 (set_attr "accum_in" "1")
2462 (set_attr "mode" "<UNITMODE>")])
2463
2464 ;;
2465 ;; ....................
2466 ;;
2467 ;; DIVISION and REMAINDER
2468 ;;
2469 ;; ....................
2470 ;;
2471
2472 (define_expand "div<mode>3"
2473 [(set (match_operand:ANYF 0 "register_operand")
2474 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
2475 (match_operand:ANYF 2 "register_operand")))]
2476 "<divide_condition>"
2477 {
2478 if (const_1_operand (operands[1], <MODE>mode))
2479 if (!(<recip_condition> && flag_unsafe_math_optimizations))
2480 operands[1] = force_reg (<MODE>mode, operands[1]);
2481 })
2482
2483 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
2484 ;;
2485 ;; If an mfc1 or dmfc1 happens to access the floating point register
2486 ;; file at the same time a long latency operation (div, sqrt, recip,
2487 ;; sqrt) iterates an intermediate result back through the floating
2488 ;; point register file bypass, then instead returning the correct
2489 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2490 ;; result of the long latency operation.
2491 ;;
2492 ;; The workaround is to insert an unconditional 'mov' from/to the
2493 ;; long latency op destination register.
2494
2495 (define_insn "*div<mode>3"
2496 [(set (match_operand:ANYF 0 "register_operand" "=f")
2497 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
2498 (match_operand:ANYF 2 "register_operand" "f")))]
2499 "<divide_condition>"
2500 {
2501 if (TARGET_FIX_SB1)
2502 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
2503 else
2504 return "div.<fmt>\t%0,%1,%2";
2505 }
2506 [(set_attr "type" "fdiv")
2507 (set_attr "mode" "<UNITMODE>")
2508 (set (attr "length")
2509 (if_then_else (match_test "TARGET_FIX_SB1")
2510 (const_int 8)
2511 (const_int 4)))])
2512
2513 (define_insn "*recip<mode>3"
2514 [(set (match_operand:ANYF 0 "register_operand" "=f")
2515 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2516 (match_operand:ANYF 2 "register_operand" "f")))]
2517 "<recip_condition> && flag_unsafe_math_optimizations"
2518 {
2519 if (TARGET_FIX_SB1)
2520 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2521 else
2522 return "recip.<fmt>\t%0,%2";
2523 }
2524 [(set_attr "type" "frdiv")
2525 (set_attr "mode" "<UNITMODE>")
2526 (set (attr "length")
2527 (if_then_else (match_test "TARGET_FIX_SB1")
2528 (const_int 8)
2529 (const_int 4)))])
2530
2531 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2532 ;; with negative operands. We use special libgcc functions instead.
2533 (define_expand "divmod<mode>4"
2534 [(set (match_operand:GPR 0 "register_operand")
2535 (div:GPR (match_operand:GPR 1 "register_operand")
2536 (match_operand:GPR 2 "register_operand")))
2537 (set (match_operand:GPR 3 "register_operand")
2538 (mod:GPR (match_dup 1)
2539 (match_dup 2)))]
2540 "!TARGET_FIX_VR4120"
2541 {
2542 if (TARGET_MIPS16)
2543 {
2544 emit_insn (gen_divmod<mode>4_split (operands[3], operands[1],
2545 operands[2]));
2546 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, LO_REGNUM));
2547 }
2548 else
2549 emit_insn (gen_divmod<mode>4_internal (operands[0], operands[1],
2550 operands[2], operands[3]));
2551 DONE;
2552 })
2553
2554 (define_insn_and_split "divmod<mode>4_internal"
2555 [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
2556 (div:GPR (match_operand:GPR 1 "register_operand" "d")
2557 (match_operand:GPR 2 "register_operand" "d")))
2558 (set (match_operand:GPR 3 "register_operand" "=d")
2559 (mod:GPR (match_dup 1)
2560 (match_dup 2)))]
2561 "!TARGET_FIX_VR4120 && !TARGET_MIPS16"
2562 "#"
2563 "&& reload_completed"
2564 [(const_int 0)]
2565 {
2566 emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
2567 DONE;
2568 }
2569 [(set_attr "type" "idiv")
2570 (set_attr "mode" "<MODE>")
2571 (set_attr "length" "8")])
2572
2573 (define_expand "udivmod<mode>4"
2574 [(set (match_operand:GPR 0 "register_operand")
2575 (udiv:GPR (match_operand:GPR 1 "register_operand")
2576 (match_operand:GPR 2 "register_operand")))
2577 (set (match_operand:GPR 3 "register_operand")
2578 (umod:GPR (match_dup 1)
2579 (match_dup 2)))]
2580 ""
2581 {
2582 if (TARGET_MIPS16)
2583 {
2584 emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1],
2585 operands[2]));
2586 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, LO_REGNUM));
2587 }
2588 else
2589 emit_insn (gen_udivmod<mode>4_internal (operands[0], operands[1],
2590 operands[2], operands[3]));
2591 DONE;
2592 })
2593
2594 (define_insn_and_split "udivmod<mode>4_internal"
2595 [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
2596 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
2597 (match_operand:GPR 2 "register_operand" "d")))
2598 (set (match_operand:GPR 3 "register_operand" "=d")
2599 (umod:GPR (match_dup 1)
2600 (match_dup 2)))]
2601 "!TARGET_MIPS16"
2602 "#"
2603 "reload_completed"
2604 [(const_int 0)]
2605 {
2606 emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
2607 DONE;
2608 }
2609 [(set_attr "type" "idiv")
2610 (set_attr "mode" "<MODE>")
2611 (set_attr "length" "8")])
2612
2613 (define_expand "<u>divmod<mode>4_split"
2614 [(set (match_operand:GPR 0 "register_operand")
2615 (any_mod:GPR (match_operand:GPR 1 "register_operand")
2616 (match_operand:GPR 2 "register_operand")))]
2617 ""
2618 {
2619 rtx hilo;
2620
2621 if (TARGET_64BIT)
2622 {
2623 hilo = gen_rtx_REG (TImode, MD_REG_FIRST);
2624 emit_insn (gen_<u>divmod<mode>4_hilo_ti (hilo, operands[1],
2625 operands[2]));
2626 emit_insn (gen_mfhi<mode>_ti (operands[0], hilo));
2627 }
2628 else
2629 {
2630 hilo = gen_rtx_REG (DImode, MD_REG_FIRST);
2631 emit_insn (gen_<u>divmod<mode>4_hilo_di (hilo, operands[1],
2632 operands[2]));
2633 emit_insn (gen_mfhi<mode>_di (operands[0], hilo));
2634 }
2635 DONE;
2636 })
2637
2638 (define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>"
2639 [(set (match_operand:HILO 0 "muldiv_target_operand" "=x")
2640 (unspec:HILO
2641 [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
2642 (match_operand:GPR 2 "register_operand" "d"))]
2643 UNSPEC_SET_HILO))]
2644 ""
2645 { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
2646 [(set_attr "type" "idiv")
2647 (set_attr "mode" "<GPR:MODE>")])
2648 \f
2649 ;;
2650 ;; ....................
2651 ;;
2652 ;; SQUARE ROOT
2653 ;;
2654 ;; ....................
2655
2656 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
2657 ;; "*div[sd]f3" comment for details).
2658
2659 (define_insn "sqrt<mode>2"
2660 [(set (match_operand:ANYF 0 "register_operand" "=f")
2661 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2662 "<sqrt_condition>"
2663 {
2664 if (TARGET_FIX_SB1)
2665 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
2666 else
2667 return "sqrt.<fmt>\t%0,%1";
2668 }
2669 [(set_attr "type" "fsqrt")
2670 (set_attr "mode" "<UNITMODE>")
2671 (set (attr "length")
2672 (if_then_else (match_test "TARGET_FIX_SB1")
2673 (const_int 8)
2674 (const_int 4)))])
2675
2676 (define_insn "*rsqrt<mode>a"
2677 [(set (match_operand:ANYF 0 "register_operand" "=f")
2678 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2679 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2680 "<recip_condition> && flag_unsafe_math_optimizations"
2681 {
2682 if (TARGET_FIX_SB1)
2683 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2684 else
2685 return "rsqrt.<fmt>\t%0,%2";
2686 }
2687 [(set_attr "type" "frsqrt")
2688 (set_attr "mode" "<UNITMODE>")
2689 (set (attr "length")
2690 (if_then_else (match_test "TARGET_FIX_SB1")
2691 (const_int 8)
2692 (const_int 4)))])
2693
2694 (define_insn "*rsqrt<mode>b"
2695 [(set (match_operand:ANYF 0 "register_operand" "=f")
2696 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2697 (match_operand:ANYF 2 "register_operand" "f"))))]
2698 "<recip_condition> && flag_unsafe_math_optimizations"
2699 {
2700 if (TARGET_FIX_SB1)
2701 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2702 else
2703 return "rsqrt.<fmt>\t%0,%2";
2704 }
2705 [(set_attr "type" "frsqrt")
2706 (set_attr "mode" "<UNITMODE>")
2707 (set (attr "length")
2708 (if_then_else (match_test "TARGET_FIX_SB1")
2709 (const_int 8)
2710 (const_int 4)))])
2711 \f
2712 ;;
2713 ;; ....................
2714 ;;
2715 ;; ABSOLUTE VALUE
2716 ;;
2717 ;; ....................
2718
2719 ;; Do not use the integer abs macro instruction, since that signals an
2720 ;; exception on -2147483648 (sigh).
2721
2722 ;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
2723 ;; invalid; it does not clear their sign bits. We therefore can't use
2724 ;; abs.fmt if the signs of NaNs matter.
2725
2726 (define_insn "abs<mode>2"
2727 [(set (match_operand:ANYF 0 "register_operand" "=f")
2728 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2729 "!HONOR_NANS (<MODE>mode)"
2730 "abs.<fmt>\t%0,%1"
2731 [(set_attr "type" "fabs")
2732 (set_attr "mode" "<UNITMODE>")])
2733 \f
2734 ;;
2735 ;; ...................
2736 ;;
2737 ;; Count leading zeroes.
2738 ;;
2739 ;; ...................
2740 ;;
2741
2742 (define_insn "clz<mode>2"
2743 [(set (match_operand:GPR 0 "register_operand" "=d")
2744 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2745 "ISA_HAS_CLZ_CLO"
2746 "<d>clz\t%0,%1"
2747 [(set_attr "type" "clz")
2748 (set_attr "mode" "<MODE>")])
2749
2750 ;;
2751 ;; ...................
2752 ;;
2753 ;; Count number of set bits.
2754 ;;
2755 ;; ...................
2756 ;;
2757
2758 (define_insn "popcount<mode>2"
2759 [(set (match_operand:GPR 0 "register_operand" "=d")
2760 (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))]
2761 "ISA_HAS_POP"
2762 "<d>pop\t%0,%1"
2763 [(set_attr "type" "pop")
2764 (set_attr "mode" "<MODE>")])
2765
2766 ;; The POP instruction is special as it does not take into account the upper
2767 ;; 32bits and is documented that way.
2768 (define_insn "*popcountdi2_trunc"
2769 [(set (match_operand:SI 0 "register_operand" "=d")
2770 (popcount:SI (truncate:SI (match_operand:DI 1 "register_operand" "d"))))]
2771 "ISA_HAS_POP && TARGET_64BIT"
2772 "pop\t%0,%1"
2773 [(set_attr "type" "pop")
2774 (set_attr "mode" "SI")])
2775 \f
2776 ;;
2777 ;; ....................
2778 ;;
2779 ;; NEGATION and ONE'S COMPLEMENT
2780 ;;
2781 ;; ....................
2782
2783 (define_insn "negsi2"
2784 [(set (match_operand:SI 0 "register_operand" "=d")
2785 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2786 ""
2787 {
2788 if (TARGET_MIPS16)
2789 return "neg\t%0,%1";
2790 else
2791 return "subu\t%0,%.,%1";
2792 }
2793 [(set_attr "alu_type" "sub")
2794 (set_attr "mode" "SI")])
2795
2796 (define_insn "negdi2"
2797 [(set (match_operand:DI 0 "register_operand" "=d")
2798 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2799 "TARGET_64BIT && !TARGET_MIPS16"
2800 "dsubu\t%0,%.,%1"
2801 [(set_attr "alu_type" "sub")
2802 (set_attr "mode" "DI")])
2803
2804 ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2805 ;; invalid; it does not flip their sign bit. We therefore can't use
2806 ;; neg.fmt if the signs of NaNs matter.
2807
2808 (define_insn "neg<mode>2"
2809 [(set (match_operand:ANYF 0 "register_operand" "=f")
2810 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2811 "!HONOR_NANS (<MODE>mode)"
2812 "neg.<fmt>\t%0,%1"
2813 [(set_attr "type" "fneg")
2814 (set_attr "mode" "<UNITMODE>")])
2815
2816 (define_insn "one_cmpl<mode>2"
2817 [(set (match_operand:GPR 0 "register_operand" "=d")
2818 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2819 ""
2820 {
2821 if (TARGET_MIPS16)
2822 return "not\t%0,%1";
2823 else
2824 return "nor\t%0,%.,%1";
2825 }
2826 [(set_attr "alu_type" "not")
2827 (set_attr "mode" "<MODE>")])
2828 \f
2829 ;;
2830 ;; ....................
2831 ;;
2832 ;; LOGICAL
2833 ;;
2834 ;; ....................
2835 ;;
2836
2837 ;; Many of these instructions use trivial define_expands, because we
2838 ;; want to use a different set of constraints when TARGET_MIPS16.
2839
2840 (define_expand "and<mode>3"
2841 [(set (match_operand:GPR 0 "register_operand")
2842 (and:GPR (match_operand:GPR 1 "register_operand")
2843 (match_operand:GPR 2 "and_reg_operand")))])
2844
2845 ;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
2846 ;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
2847 ;; Note that this variant does not trigger for SI mode because we require
2848 ;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
2849 ;; sign-extended SImode value.
2850 ;;
2851 ;; These are possible combinations for operand 1 and 2. The table
2852 ;; includes both MIPS and MIPS16 cases. (r=register, mem=memory,
2853 ;; 16=MIPS16, x=match, S=split):
2854 ;;
2855 ;; \ op1 r/EXT r/!EXT mem r/16 mem/16
2856 ;; op2
2857 ;;
2858 ;; andi x x
2859 ;; 0xff x x x x
2860 ;; 0xffff x x x x
2861 ;; 0xffff_ffff x S x S x
2862 ;; low-bitmask x
2863 ;; register x x
2864 ;; register =op1 x
2865
2866 (define_insn "*and<mode>3"
2867 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d,d")
2868 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,d,d,d,d")
2869 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,K,Yx,Yw,d")))]
2870 "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
2871 {
2872 int len;
2873
2874 switch (which_alternative)
2875 {
2876 case 0:
2877 operands[1] = gen_lowpart (QImode, operands[1]);
2878 return "lbu\t%0,%1";
2879 case 1:
2880 operands[1] = gen_lowpart (HImode, operands[1]);
2881 return "lhu\t%0,%1";
2882 case 2:
2883 operands[1] = gen_lowpart (SImode, operands[1]);
2884 return "lwu\t%0,%1";
2885 case 3:
2886 return "andi\t%0,%1,%x2";
2887 case 4:
2888 len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
2889 operands[2] = GEN_INT (len);
2890 return "<d>ext\t%0,%1,0,%2";
2891 case 5:
2892 return "#";
2893 case 6:
2894 return "and\t%0,%1,%2";
2895 default:
2896 gcc_unreachable ();
2897 }
2898 }
2899 [(set_attr "move_type" "load,load,load,andi,ext_ins,shift_shift,logical")
2900 (set_attr "mode" "<MODE>")])
2901
2902 (define_insn "*and<mode>3_mips16"
2903 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
2904 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%o,o,W,d,0")
2905 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
2906 "TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
2907 {
2908 switch (which_alternative)
2909 {
2910 case 0:
2911 operands[1] = gen_lowpart (QImode, operands[1]);
2912 return "lbu\t%0,%1";
2913 case 1:
2914 operands[1] = gen_lowpart (HImode, operands[1]);
2915 return "lhu\t%0,%1";
2916 case 2:
2917 operands[1] = gen_lowpart (SImode, operands[1]);
2918 return "lwu\t%0,%1";
2919 case 3:
2920 return "#";
2921 case 4:
2922 return "and\t%0,%2";
2923 default:
2924 gcc_unreachable ();
2925 }
2926 }
2927 [(set_attr "move_type" "load,load,load,shift_shift,logical")
2928 (set_attr "mode" "<MODE>")])
2929
2930 (define_expand "ior<mode>3"
2931 [(set (match_operand:GPR 0 "register_operand")
2932 (ior:GPR (match_operand:GPR 1 "register_operand")
2933 (match_operand:GPR 2 "uns_arith_operand")))]
2934 ""
2935 {
2936 if (TARGET_MIPS16)
2937 operands[2] = force_reg (<MODE>mode, operands[2]);
2938 })
2939
2940 (define_insn "*ior<mode>3"
2941 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2942 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2943 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2944 "!TARGET_MIPS16"
2945 "@
2946 or\t%0,%1,%2
2947 ori\t%0,%1,%x2"
2948 [(set_attr "alu_type" "or")
2949 (set_attr "mode" "<MODE>")])
2950
2951 (define_insn "*ior<mode>3_mips16"
2952 [(set (match_operand:GPR 0 "register_operand" "=d")
2953 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2954 (match_operand:GPR 2 "register_operand" "d")))]
2955 "TARGET_MIPS16"
2956 "or\t%0,%2"
2957 [(set_attr "alu_type" "or")
2958 (set_attr "mode" "<MODE>")])
2959
2960 (define_expand "xor<mode>3"
2961 [(set (match_operand:GPR 0 "register_operand")
2962 (xor:GPR (match_operand:GPR 1 "register_operand")
2963 (match_operand:GPR 2 "uns_arith_operand")))]
2964 ""
2965 "")
2966
2967 (define_insn ""
2968 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2969 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2970 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2971 "!TARGET_MIPS16"
2972 "@
2973 xor\t%0,%1,%2
2974 xori\t%0,%1,%x2"
2975 [(set_attr "alu_type" "xor")
2976 (set_attr "mode" "<MODE>")])
2977
2978 (define_insn ""
2979 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2980 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2981 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2982 "TARGET_MIPS16"
2983 "@
2984 xor\t%0,%2
2985 cmpi\t%1,%2
2986 cmp\t%1,%2"
2987 [(set_attr "alu_type" "xor")
2988 (set_attr "mode" "<MODE>")
2989 (set_attr_alternative "length"
2990 [(const_int 4)
2991 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2992 (const_int 4)
2993 (const_int 8))
2994 (const_int 4)])])
2995
2996 (define_insn "*nor<mode>3"
2997 [(set (match_operand:GPR 0 "register_operand" "=d")
2998 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2999 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
3000 "!TARGET_MIPS16"
3001 "nor\t%0,%1,%2"
3002 [(set_attr "alu_type" "nor")
3003 (set_attr "mode" "<MODE>")])
3004 \f
3005 ;;
3006 ;; ....................
3007 ;;
3008 ;; TRUNCATION
3009 ;;
3010 ;; ....................
3011
3012
3013
3014 (define_insn "truncdfsf2"
3015 [(set (match_operand:SF 0 "register_operand" "=f")
3016 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3017 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3018 "cvt.s.d\t%0,%1"
3019 [(set_attr "type" "fcvt")
3020 (set_attr "cnv_mode" "D2S")
3021 (set_attr "mode" "SF")])
3022
3023 ;; Integer truncation patterns. Truncating SImode values to smaller
3024 ;; modes is a no-op, as it is for most other GCC ports. Truncating
3025 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3026 ;; need to make sure that the lower 32 bits are properly sign-extended
3027 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
3028 ;; smaller than SImode is equivalent to two separate truncations:
3029 ;;
3030 ;; A B
3031 ;; DI ---> HI == DI ---> SI ---> HI
3032 ;; DI ---> QI == DI ---> SI ---> QI
3033 ;;
3034 ;; Step A needs a real instruction but step B does not.
3035
3036 (define_insn "truncdi<mode>2"
3037 [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m")
3038 (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))]
3039 "TARGET_64BIT"
3040 "@
3041 sll\t%0,%1,0
3042 <store>\t%1,%0"
3043 [(set_attr "move_type" "sll0,store")
3044 (set_attr "mode" "SI")])
3045
3046 ;; Combiner patterns to optimize shift/truncate combinations.
3047
3048 (define_insn "*ashr_trunc<mode>"
3049 [(set (match_operand:SUBDI 0 "register_operand" "=d")
3050 (truncate:SUBDI
3051 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3052 (match_operand:DI 2 "const_arith_operand" ""))))]
3053 "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3054 "dsra\t%0,%1,%2"
3055 [(set_attr "type" "shift")
3056 (set_attr "mode" "<MODE>")])
3057
3058 (define_insn "*lshr32_trunc<mode>"
3059 [(set (match_operand:SUBDI 0 "register_operand" "=d")
3060 (truncate:SUBDI
3061 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3062 (const_int 32))))]
3063 "TARGET_64BIT && !TARGET_MIPS16"
3064 "dsra\t%0,%1,32"
3065 [(set_attr "type" "shift")
3066 (set_attr "mode" "<MODE>")])
3067
3068 ;; Logical shift by more than 32 results in proper SI values so truncation is
3069 ;; removed by the middle end. Note that a logical shift by 32 is handled by
3070 ;; the previous pattern.
3071 (define_insn "*<optab>_trunc<mode>_exts"
3072 [(set (match_operand:SUBDI 0 "register_operand" "=d")
3073 (truncate:SUBDI
3074 (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
3075 (match_operand:DI 2 "const_arith_operand" ""))))]
3076 "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
3077 "exts\t%0,%1,%2,31"
3078 [(set_attr "type" "arith")
3079 (set_attr "mode" "<MODE>")])
3080 \f
3081 ;;
3082 ;; ....................
3083 ;;
3084 ;; ZERO EXTENSION
3085 ;;
3086 ;; ....................
3087
3088 ;; Extension insns.
3089
3090 (define_expand "zero_extendsidi2"
3091 [(set (match_operand:DI 0 "register_operand")
3092 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3093 "TARGET_64BIT")
3094
3095 (define_insn_and_split "*zero_extendsidi2"
3096 [(set (match_operand:DI 0 "register_operand" "=d,d")
3097 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3098 "TARGET_64BIT && !ISA_HAS_EXT_INS"
3099 "@
3100 #
3101 lwu\t%0,%1"
3102 "&& reload_completed && REG_P (operands[1])"
3103 [(set (match_dup 0)
3104 (ashift:DI (match_dup 1) (const_int 32)))
3105 (set (match_dup 0)
3106 (lshiftrt:DI (match_dup 0) (const_int 32)))]
3107 { operands[1] = gen_lowpart (DImode, operands[1]); }
3108 [(set_attr "move_type" "shift_shift,load")
3109 (set_attr "mode" "DI")])
3110
3111 (define_insn "*zero_extendsidi2_dext"
3112 [(set (match_operand:DI 0 "register_operand" "=d,d")
3113 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
3114 "TARGET_64BIT && ISA_HAS_EXT_INS"
3115 "@
3116 dext\t%0,%1,0,32
3117 lwu\t%0,%1"
3118 [(set_attr "move_type" "arith,load")
3119 (set_attr "mode" "DI")])
3120
3121 ;; See the comment before the *and<mode>3 pattern why this is generated by
3122 ;; combine.
3123
3124 (define_split
3125 [(set (match_operand:DI 0 "register_operand")
3126 (and:DI (match_operand:DI 1 "register_operand")
3127 (const_int 4294967295)))]
3128 "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed"
3129 [(set (match_dup 0)
3130 (ashift:DI (match_dup 1) (const_int 32)))
3131 (set (match_dup 0)
3132 (lshiftrt:DI (match_dup 0) (const_int 32)))])
3133
3134 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
3135 [(set (match_operand:GPR 0 "register_operand")
3136 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3137 ""
3138 {
3139 if (TARGET_MIPS16 && !GENERATE_MIPS16E
3140 && !memory_operand (operands[1], <SHORT:MODE>mode))
3141 {
3142 emit_insn (gen_and<GPR:mode>3 (operands[0],
3143 gen_lowpart (<GPR:MODE>mode, operands[1]),
3144 force_reg (<GPR:MODE>mode,
3145 GEN_INT (<SHORT:mask>))));
3146 DONE;
3147 }
3148 })
3149
3150 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
3151 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3152 (zero_extend:GPR
3153 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3154 "!TARGET_MIPS16"
3155 "@
3156 andi\t%0,%1,<SHORT:mask>
3157 l<SHORT:size>u\t%0,%1"
3158 [(set_attr "move_type" "andi,load")
3159 (set_attr "mode" "<GPR:MODE>")])
3160
3161 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
3162 [(set (match_operand:GPR 0 "register_operand" "=d")
3163 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
3164 "GENERATE_MIPS16E"
3165 "ze<SHORT:size>\t%0"
3166 ;; This instruction is effectively a special encoding of ANDI.
3167 [(set_attr "move_type" "andi")
3168 (set_attr "mode" "<GPR:MODE>")])
3169
3170 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
3171 [(set (match_operand:GPR 0 "register_operand" "=d")
3172 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
3173 "TARGET_MIPS16"
3174 "l<SHORT:size>u\t%0,%1"
3175 [(set_attr "move_type" "load")
3176 (set_attr "mode" "<GPR:MODE>")])
3177
3178 (define_expand "zero_extendqihi2"
3179 [(set (match_operand:HI 0 "register_operand")
3180 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3181 ""
3182 {
3183 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
3184 {
3185 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
3186 operands[1]));
3187 DONE;
3188 }
3189 })
3190
3191 (define_insn "*zero_extendqihi2"
3192 [(set (match_operand:HI 0 "register_operand" "=d,d")
3193 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3194 "!TARGET_MIPS16"
3195 "@
3196 andi\t%0,%1,0x00ff
3197 lbu\t%0,%1"
3198 [(set_attr "move_type" "andi,load")
3199 (set_attr "mode" "HI")])
3200
3201 (define_insn "*zero_extendqihi2_mips16"
3202 [(set (match_operand:HI 0 "register_operand" "=d")
3203 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3204 "TARGET_MIPS16"
3205 "lbu\t%0,%1"
3206 [(set_attr "move_type" "load")
3207 (set_attr "mode" "HI")])
3208
3209 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3210
3211 (define_insn "*zero_extend<GPR:mode>_trunc<SHORT:mode>"
3212 [(set (match_operand:GPR 0 "register_operand" "=d")
3213 (zero_extend:GPR
3214 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3215 "TARGET_64BIT && !TARGET_MIPS16"
3216 {
3217 operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode));
3218 return "andi\t%0,%1,%x2";
3219 }
3220 [(set_attr "alu_type" "and")
3221 (set_attr "mode" "<GPR:MODE>")])
3222
3223 (define_insn "*zero_extendhi_truncqi"
3224 [(set (match_operand:HI 0 "register_operand" "=d")
3225 (zero_extend:HI
3226 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3227 "TARGET_64BIT && !TARGET_MIPS16"
3228 "andi\t%0,%1,0xff"
3229 [(set_attr "alu_type" "and")
3230 (set_attr "mode" "HI")])
3231 \f
3232 ;;
3233 ;; ....................
3234 ;;
3235 ;; SIGN EXTENSION
3236 ;;
3237 ;; ....................
3238
3239 ;; Extension insns.
3240 ;; Those for integer source operand are ordered widest source type first.
3241
3242 ;; When TARGET_64BIT, all SImode integer and accumulator registers
3243 ;; should already be in sign-extended form (see TRULY_NOOP_TRUNCATION
3244 ;; and truncdisi2). We can therefore get rid of register->register
3245 ;; instructions if we constrain the source to be in the same register as
3246 ;; the destination.
3247 ;;
3248 ;; Only the pre-reload scheduler sees the type of the register alternatives;
3249 ;; we split them into nothing before the post-reload scheduler runs.
3250 ;; These alternatives therefore have type "move" in order to reflect
3251 ;; what happens if the two pre-reload operands cannot be tied, and are
3252 ;; instead allocated two separate GPRs. We don't distinguish between
3253 ;; the GPR and LO cases because we don't usually know during pre-reload
3254 ;; scheduling whether an operand will be LO or not.
3255 (define_insn_and_split "extendsidi2"
3256 [(set (match_operand:DI 0 "register_operand" "=d,l,d")
3257 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,0,m")))]
3258 "TARGET_64BIT"
3259 "@
3260 #
3261 #
3262 lw\t%0,%1"
3263 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3264 [(const_int 0)]
3265 {
3266 emit_note (NOTE_INSN_DELETED);
3267 DONE;
3268 }
3269 [(set_attr "move_type" "move,move,load")
3270 (set_attr "mode" "DI")])
3271
3272 (define_expand "extend<SHORT:mode><GPR:mode>2"
3273 [(set (match_operand:GPR 0 "register_operand")
3274 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
3275 "")
3276
3277 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
3278 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3279 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
3280 "GENERATE_MIPS16E"
3281 "@
3282 se<SHORT:size>\t%0
3283 l<SHORT:size>\t%0,%1"
3284 [(set_attr "move_type" "signext,load")
3285 (set_attr "mode" "<GPR:MODE>")])
3286
3287 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
3288 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3289 (sign_extend:GPR
3290 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3291 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3292 "@
3293 #
3294 l<SHORT:size>\t%0,%1"
3295 "&& reload_completed && REG_P (operands[1])"
3296 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
3297 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
3298 {
3299 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
3300 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
3301 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
3302 }
3303 [(set_attr "move_type" "shift_shift,load")
3304 (set_attr "mode" "<GPR:MODE>")])
3305
3306 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
3307 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3308 (sign_extend:GPR
3309 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
3310 "ISA_HAS_SEB_SEH"
3311 "@
3312 se<SHORT:size>\t%0,%1
3313 l<SHORT:size>\t%0,%1"
3314 [(set_attr "move_type" "signext,load")
3315 (set_attr "mode" "<GPR:MODE>")])
3316
3317 (define_expand "extendqihi2"
3318 [(set (match_operand:HI 0 "register_operand")
3319 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3320 "")
3321
3322 (define_insn "*extendqihi2_mips16e"
3323 [(set (match_operand:HI 0 "register_operand" "=d,d")
3324 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
3325 "GENERATE_MIPS16E"
3326 "@
3327 seb\t%0
3328 lb\t%0,%1"
3329 [(set_attr "move_type" "signext,load")
3330 (set_attr "mode" "SI")])
3331
3332 (define_insn_and_split "*extendqihi2"
3333 [(set (match_operand:HI 0 "register_operand" "=d,d")
3334 (sign_extend:HI
3335 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3336 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
3337 "@
3338 #
3339 lb\t%0,%1"
3340 "&& reload_completed && REG_P (operands[1])"
3341 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3342 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
3343 {
3344 operands[0] = gen_lowpart (SImode, operands[0]);
3345 operands[1] = gen_lowpart (SImode, operands[1]);
3346 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
3347 - GET_MODE_BITSIZE (QImode));
3348 }
3349 [(set_attr "move_type" "shift_shift,load")
3350 (set_attr "mode" "SI")])
3351
3352 (define_insn "*extendqihi2_seb"
3353 [(set (match_operand:HI 0 "register_operand" "=d,d")
3354 (sign_extend:HI
3355 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3356 "ISA_HAS_SEB_SEH"
3357 "@
3358 seb\t%0,%1
3359 lb\t%0,%1"
3360 [(set_attr "move_type" "signext,load")
3361 (set_attr "mode" "SI")])
3362
3363 ;; Combiner patterns for truncate/sign_extend combinations. The SI versions
3364 ;; use the shift/truncate patterns.
3365
3366 (define_insn_and_split "*extenddi_truncate<mode>"
3367 [(set (match_operand:DI 0 "register_operand" "=d")
3368 (sign_extend:DI
3369 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3370 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3371 "#"
3372 "&& reload_completed"
3373 [(set (match_dup 2)
3374 (ashift:DI (match_dup 1)
3375 (match_dup 3)))
3376 (set (match_dup 0)
3377 (ashiftrt:DI (match_dup 2)
3378 (match_dup 3)))]
3379 {
3380 operands[2] = gen_lowpart (DImode, operands[0]);
3381 operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3382 }
3383 [(set_attr "move_type" "shift_shift")
3384 (set_attr "mode" "DI")])
3385
3386 (define_insn_and_split "*extendsi_truncate<mode>"
3387 [(set (match_operand:SI 0 "register_operand" "=d")
3388 (sign_extend:SI
3389 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3390 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3391 "#"
3392 "&& reload_completed"
3393 [(set (match_dup 2)
3394 (ashift:DI (match_dup 1)
3395 (match_dup 3)))
3396 (set (match_dup 0)
3397 (truncate:SI (ashiftrt:DI (match_dup 2)
3398 (match_dup 3))))]
3399 {
3400 operands[2] = gen_lowpart (DImode, operands[0]);
3401 operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
3402 }
3403 [(set_attr "move_type" "shift_shift")
3404 (set_attr "mode" "SI")])
3405
3406 (define_insn_and_split "*extendhi_truncateqi"
3407 [(set (match_operand:HI 0 "register_operand" "=d")
3408 (sign_extend:HI
3409 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3410 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS"
3411 "#"
3412 "&& reload_completed"
3413 [(set (match_dup 2)
3414 (ashift:DI (match_dup 1)
3415 (const_int 56)))
3416 (set (match_dup 0)
3417 (truncate:HI (ashiftrt:DI (match_dup 2)
3418 (const_int 56))))]
3419 {
3420 operands[2] = gen_lowpart (DImode, operands[0]);
3421 }
3422 [(set_attr "move_type" "shift_shift")
3423 (set_attr "mode" "SI")])
3424
3425 (define_insn "*extend<GPR:mode>_truncate<SHORT:mode>_exts"
3426 [(set (match_operand:GPR 0 "register_operand" "=d")
3427 (sign_extend:GPR
3428 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
3429 "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3430 {
3431 operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
3432 return "exts\t%0,%1,0,%m2";
3433 }
3434 [(set_attr "type" "arith")
3435 (set_attr "mode" "<GPR:MODE>")])
3436
3437 (define_insn "*extendhi_truncateqi_exts"
3438 [(set (match_operand:HI 0 "register_operand" "=d")
3439 (sign_extend:HI
3440 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3441 "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS"
3442 "exts\t%0,%1,0,7"
3443 [(set_attr "type" "arith")
3444 (set_attr "mode" "SI")])
3445
3446 (define_insn "extendsfdf2"
3447 [(set (match_operand:DF 0 "register_operand" "=f")
3448 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3449 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3450 "cvt.d.s\t%0,%1"
3451 [(set_attr "type" "fcvt")
3452 (set_attr "cnv_mode" "S2D")
3453 (set_attr "mode" "DF")])
3454 \f
3455 ;;
3456 ;; ....................
3457 ;;
3458 ;; CONVERSIONS
3459 ;;
3460 ;; ....................
3461
3462 (define_expand "fix_truncdfsi2"
3463 [(set (match_operand:SI 0 "register_operand")
3464 (fix:SI (match_operand:DF 1 "register_operand")))]
3465 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3466 {
3467 if (!ISA_HAS_TRUNC_W)
3468 {
3469 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3470 DONE;
3471 }
3472 })
3473
3474 (define_insn "fix_truncdfsi2_insn"
3475 [(set (match_operand:SI 0 "register_operand" "=f")
3476 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3477 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3478 "trunc.w.d %0,%1"
3479 [(set_attr "type" "fcvt")
3480 (set_attr "mode" "DF")
3481 (set_attr "cnv_mode" "D2I")])
3482
3483 (define_insn "fix_truncdfsi2_macro"
3484 [(set (match_operand:SI 0 "register_operand" "=f")
3485 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3486 (clobber (match_scratch:DF 2 "=d"))]
3487 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3488 {
3489 if (mips_nomacro.nesting_level > 0)
3490 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3491 else
3492 return "trunc.w.d %0,%1,%2";
3493 }
3494 [(set_attr "type" "fcvt")
3495 (set_attr "mode" "DF")
3496 (set_attr "cnv_mode" "D2I")
3497 (set_attr "length" "36")])
3498
3499 (define_expand "fix_truncsfsi2"
3500 [(set (match_operand:SI 0 "register_operand")
3501 (fix:SI (match_operand:SF 1 "register_operand")))]
3502 "TARGET_HARD_FLOAT"
3503 {
3504 if (!ISA_HAS_TRUNC_W)
3505 {
3506 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3507 DONE;
3508 }
3509 })
3510
3511 (define_insn "fix_truncsfsi2_insn"
3512 [(set (match_operand:SI 0 "register_operand" "=f")
3513 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3514 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3515 "trunc.w.s %0,%1"
3516 [(set_attr "type" "fcvt")
3517 (set_attr "mode" "SF")
3518 (set_attr "cnv_mode" "S2I")])
3519
3520 (define_insn "fix_truncsfsi2_macro"
3521 [(set (match_operand:SI 0 "register_operand" "=f")
3522 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3523 (clobber (match_scratch:SF 2 "=d"))]
3524 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3525 {
3526 if (mips_nomacro.nesting_level > 0)
3527 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3528 else
3529 return "trunc.w.s %0,%1,%2";
3530 }
3531 [(set_attr "type" "fcvt")
3532 (set_attr "mode" "SF")
3533 (set_attr "cnv_mode" "S2I")
3534 (set_attr "length" "36")])
3535
3536
3537 (define_insn "fix_truncdfdi2"
3538 [(set (match_operand:DI 0 "register_operand" "=f")
3539 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3540 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3541 "trunc.l.d %0,%1"
3542 [(set_attr "type" "fcvt")
3543 (set_attr "mode" "DF")
3544 (set_attr "cnv_mode" "D2I")])
3545
3546
3547 (define_insn "fix_truncsfdi2"
3548 [(set (match_operand:DI 0 "register_operand" "=f")
3549 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3550 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3551 "trunc.l.s %0,%1"
3552 [(set_attr "type" "fcvt")
3553 (set_attr "mode" "SF")
3554 (set_attr "cnv_mode" "S2I")])
3555
3556
3557 (define_insn "floatsidf2"
3558 [(set (match_operand:DF 0 "register_operand" "=f")
3559 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3560 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3561 "cvt.d.w\t%0,%1"
3562 [(set_attr "type" "fcvt")
3563 (set_attr "mode" "DF")
3564 (set_attr "cnv_mode" "I2D")])
3565
3566
3567 (define_insn "floatdidf2"
3568 [(set (match_operand:DF 0 "register_operand" "=f")
3569 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3570 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3571 "cvt.d.l\t%0,%1"
3572 [(set_attr "type" "fcvt")
3573 (set_attr "mode" "DF")
3574 (set_attr "cnv_mode" "I2D")])
3575
3576
3577 (define_insn "floatsisf2"
3578 [(set (match_operand:SF 0 "register_operand" "=f")
3579 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3580 "TARGET_HARD_FLOAT"
3581 "cvt.s.w\t%0,%1"
3582 [(set_attr "type" "fcvt")
3583 (set_attr "mode" "SF")
3584 (set_attr "cnv_mode" "I2S")])
3585
3586
3587 (define_insn "floatdisf2"
3588 [(set (match_operand:SF 0 "register_operand" "=f")
3589 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3590 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3591 "cvt.s.l\t%0,%1"
3592 [(set_attr "type" "fcvt")
3593 (set_attr "mode" "SF")
3594 (set_attr "cnv_mode" "I2S")])
3595
3596
3597 (define_expand "fixuns_truncdfsi2"
3598 [(set (match_operand:SI 0 "register_operand")
3599 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3600 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3601 {
3602 rtx reg1 = gen_reg_rtx (DFmode);
3603 rtx reg2 = gen_reg_rtx (DFmode);
3604 rtx reg3 = gen_reg_rtx (SImode);
3605 rtx label1 = gen_label_rtx ();
3606 rtx label2 = gen_label_rtx ();
3607 rtx test;
3608 REAL_VALUE_TYPE offset;
3609
3610 real_2expN (&offset, 31, DFmode);
3611
3612 if (reg1) /* Turn off complaints about unreached code. */
3613 {
3614 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3615 do_pending_stack_adjust ();
3616
3617 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3618 emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3619
3620 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3621 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3622 gen_rtx_LABEL_REF (VOIDmode, label2)));
3623 emit_barrier ();
3624
3625 emit_label (label1);
3626 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3627 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3628 (BITMASK_HIGH, SImode)));
3629
3630 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3631 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3632
3633 emit_label (label2);
3634
3635 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3636 fields, and can't be used for REG_NOTES anyway). */
3637 emit_use (stack_pointer_rtx);
3638 DONE;
3639 }
3640 })
3641
3642
3643 (define_expand "fixuns_truncdfdi2"
3644 [(set (match_operand:DI 0 "register_operand")
3645 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3646 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3647 {
3648 rtx reg1 = gen_reg_rtx (DFmode);
3649 rtx reg2 = gen_reg_rtx (DFmode);
3650 rtx reg3 = gen_reg_rtx (DImode);
3651 rtx label1 = gen_label_rtx ();
3652 rtx label2 = gen_label_rtx ();
3653 rtx test;
3654 REAL_VALUE_TYPE offset;
3655
3656 real_2expN (&offset, 63, DFmode);
3657
3658 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3659 do_pending_stack_adjust ();
3660
3661 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3662 emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
3663
3664 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3665 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3666 gen_rtx_LABEL_REF (VOIDmode, label2)));
3667 emit_barrier ();
3668
3669 emit_label (label1);
3670 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3671 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3672 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3673
3674 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3675 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3676
3677 emit_label (label2);
3678
3679 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3680 fields, and can't be used for REG_NOTES anyway). */
3681 emit_use (stack_pointer_rtx);
3682 DONE;
3683 })
3684
3685
3686 (define_expand "fixuns_truncsfsi2"
3687 [(set (match_operand:SI 0 "register_operand")
3688 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3689 "TARGET_HARD_FLOAT"
3690 {
3691 rtx reg1 = gen_reg_rtx (SFmode);
3692 rtx reg2 = gen_reg_rtx (SFmode);
3693 rtx reg3 = gen_reg_rtx (SImode);
3694 rtx label1 = gen_label_rtx ();
3695 rtx label2 = gen_label_rtx ();
3696 rtx test;
3697 REAL_VALUE_TYPE offset;
3698
3699 real_2expN (&offset, 31, SFmode);
3700
3701 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3702 do_pending_stack_adjust ();
3703
3704 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3705 emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3706
3707 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3708 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3709 gen_rtx_LABEL_REF (VOIDmode, label2)));
3710 emit_barrier ();
3711
3712 emit_label (label1);
3713 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3714 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode
3715 (BITMASK_HIGH, SImode)));
3716
3717 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3718 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3719
3720 emit_label (label2);
3721
3722 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3723 fields, and can't be used for REG_NOTES anyway). */
3724 emit_use (stack_pointer_rtx);
3725 DONE;
3726 })
3727
3728
3729 (define_expand "fixuns_truncsfdi2"
3730 [(set (match_operand:DI 0 "register_operand")
3731 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3732 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3733 {
3734 rtx reg1 = gen_reg_rtx (SFmode);
3735 rtx reg2 = gen_reg_rtx (SFmode);
3736 rtx reg3 = gen_reg_rtx (DImode);
3737 rtx label1 = gen_label_rtx ();
3738 rtx label2 = gen_label_rtx ();
3739 rtx test;
3740 REAL_VALUE_TYPE offset;
3741
3742 real_2expN (&offset, 63, SFmode);
3743
3744 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3745 do_pending_stack_adjust ();
3746
3747 test = gen_rtx_GE (VOIDmode, operands[1], reg1);
3748 emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
3749
3750 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3751 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3752 gen_rtx_LABEL_REF (VOIDmode, label2)));
3753 emit_barrier ();
3754
3755 emit_label (label1);
3756 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3757 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH));
3758 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3759
3760 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3761 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3762
3763 emit_label (label2);
3764
3765 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3766 fields, and can't be used for REG_NOTES anyway). */
3767 emit_use (stack_pointer_rtx);
3768 DONE;
3769 })
3770 \f
3771 ;;
3772 ;; ....................
3773 ;;
3774 ;; DATA MOVEMENT
3775 ;;
3776 ;; ....................
3777
3778 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3779
3780 (define_expand "extvmisalign<mode>"
3781 [(set (match_operand:GPR 0 "register_operand")
3782 (sign_extract:GPR (match_operand:BLK 1 "memory_operand")
3783 (match_operand 2 "const_int_operand")
3784 (match_operand 3 "const_int_operand")))]
3785 "!TARGET_MIPS16"
3786 {
3787 if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3788 INTVAL (operands[2]),
3789 INTVAL (operands[3]),
3790 /*unsigned=*/ false))
3791 DONE;
3792 else
3793 FAIL;
3794 })
3795
3796 (define_expand "extv<mode>"
3797 [(set (match_operand:GPR 0 "register_operand")
3798 (sign_extract:GPR (match_operand:GPR 1 "register_operand")
3799 (match_operand 2 "const_int_operand")
3800 (match_operand 3 "const_int_operand")))]
3801 "ISA_HAS_EXTS"
3802 {
3803 if (UINTVAL (operands[2]) > 32)
3804 FAIL;
3805 })
3806
3807 (define_insn "*extv<mode>"
3808 [(set (match_operand:GPR 0 "register_operand" "=d")
3809 (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3810 (match_operand 2 "const_int_operand" "")
3811 (match_operand 3 "const_int_operand" "")))]
3812 "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
3813 "exts\t%0,%1,%3,%m2"
3814 [(set_attr "type" "arith")
3815 (set_attr "mode" "<MODE>")])
3816
3817 (define_expand "extzvmisalign<mode>"
3818 [(set (match_operand:GPR 0 "register_operand")
3819 (zero_extract:GPR (match_operand:BLK 1 "memory_operand")
3820 (match_operand 2 "const_int_operand")
3821 (match_operand 3 "const_int_operand")))]
3822 "!TARGET_MIPS16"
3823 {
3824 if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
3825 INTVAL (operands[2]),
3826 INTVAL (operands[3]),
3827 /*unsigned=*/ true))
3828 DONE;
3829 else
3830 FAIL;
3831 })
3832
3833 (define_expand "extzv<mode>"
3834 [(set (match_operand:GPR 0 "register_operand")
3835 (zero_extract:GPR (match_operand:GPR 1 "register_operand")
3836 (match_operand 2 "const_int_operand")
3837 (match_operand 3 "const_int_operand")))]
3838 ""
3839 {
3840 if (!mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3841 INTVAL (operands[3])))
3842 FAIL;
3843 })
3844
3845 (define_insn "*extzv<mode>"
3846 [(set (match_operand:GPR 0 "register_operand" "=d")
3847 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3848 (match_operand 2 "const_int_operand" "")
3849 (match_operand 3 "const_int_operand" "")))]
3850 "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
3851 INTVAL (operands[3]))"
3852 "<d>ext\t%0,%1,%3,%2"
3853 [(set_attr "type" "arith")
3854 (set_attr "mode" "<MODE>")])
3855
3856 (define_insn "*extzv_truncsi_exts"
3857 [(set (match_operand:SI 0 "register_operand" "=d")
3858 (truncate:SI
3859 (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
3860 (match_operand 2 "const_int_operand" "")
3861 (match_operand 3 "const_int_operand" ""))))]
3862 "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
3863 "exts\t%0,%1,%3,31"
3864 [(set_attr "type" "arith")
3865 (set_attr "mode" "SI")])
3866
3867
3868 (define_expand "insvmisalign<mode>"
3869 [(set (zero_extract:GPR (match_operand:BLK 0 "memory_operand")
3870 (match_operand 1 "const_int_operand")
3871 (match_operand 2 "const_int_operand"))
3872 (match_operand:GPR 3 "reg_or_0_operand"))]
3873 "!TARGET_MIPS16"
3874 {
3875 if (mips_expand_ins_as_unaligned_store (operands[0], operands[3],
3876 INTVAL (operands[1]),
3877 INTVAL (operands[2])))
3878 DONE;
3879 else
3880 FAIL;
3881 })
3882
3883 (define_expand "insv<mode>"
3884 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand")
3885 (match_operand 1 "const_int_operand")
3886 (match_operand 2 "const_int_operand"))
3887 (match_operand:GPR 3 "reg_or_0_operand"))]
3888 ""
3889 {
3890 if (!mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3891 INTVAL (operands[2])))
3892 FAIL;
3893 })
3894
3895 (define_insn "*insv<mode>"
3896 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3897 (match_operand:SI 1 "const_int_operand" "")
3898 (match_operand:SI 2 "const_int_operand" ""))
3899 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3900 "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]),
3901 INTVAL (operands[2]))"
3902 "<d>ins\t%0,%z3,%2,%1"
3903 [(set_attr "type" "arith")
3904 (set_attr "mode" "<MODE>")])
3905
3906 ;; Combiner pattern for cins (clear and insert bit field). We can
3907 ;; implement mask-and-shift-left operation with this. Note that if
3908 ;; the upper bit of the mask is set in an SImode operation, the mask
3909 ;; itself will be sign-extended. mask_low_and_shift_len will
3910 ;; therefore be greater than our threshold of 32.
3911
3912 (define_insn "*cins<mode>"
3913 [(set (match_operand:GPR 0 "register_operand" "=d")
3914 (and:GPR
3915 (ashift:GPR (match_operand:GPR 1 "register_operand" "d")
3916 (match_operand:GPR 2 "const_int_operand" ""))
3917 (match_operand:GPR 3 "const_int_operand" "")))]
3918 "ISA_HAS_CINS
3919 && mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)"
3920 {
3921 operands[3] =
3922 GEN_INT (mask_low_and_shift_len (<MODE>mode, operands[3], operands[2]));
3923 return "cins\t%0,%1,%2,%m3";
3924 }
3925 [(set_attr "type" "shift")
3926 (set_attr "mode" "<MODE>")])
3927
3928 ;; Unaligned word moves generated by the bit field patterns.
3929 ;;
3930 ;; As far as the rtl is concerned, both the left-part and right-part
3931 ;; instructions can access the whole field. However, the real operand
3932 ;; refers to just the first or the last byte (depending on endianness).
3933 ;; We therefore use two memory operands to each instruction, one to
3934 ;; describe the rtl effect and one to use in the assembly output.
3935 ;;
3936 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3937 ;; This allows us to use the standard length calculations for the "load"
3938 ;; and "store" type attributes.
3939
3940 (define_insn "mov_<load>l"
3941 [(set (match_operand:GPR 0 "register_operand" "=d")
3942 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3943 (match_operand:QI 2 "memory_operand" "m")]
3944 UNSPEC_LOAD_LEFT))]
3945 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3946 "<load>l\t%0,%2"
3947 [(set_attr "move_type" "load")
3948 (set_attr "mode" "<MODE>")])
3949
3950 (define_insn "mov_<load>r"
3951 [(set (match_operand:GPR 0 "register_operand" "=d")
3952 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3953 (match_operand:QI 2 "memory_operand" "m")
3954 (match_operand:GPR 3 "register_operand" "0")]
3955 UNSPEC_LOAD_RIGHT))]
3956 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3957 "<load>r\t%0,%2"
3958 [(set_attr "move_type" "load")
3959 (set_attr "mode" "<MODE>")])
3960
3961 (define_insn "mov_<store>l"
3962 [(set (match_operand:BLK 0 "memory_operand" "=m")
3963 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3964 (match_operand:QI 2 "memory_operand" "m")]
3965 UNSPEC_STORE_LEFT))]
3966 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3967 "<store>l\t%z1,%2"
3968 [(set_attr "move_type" "store")
3969 (set_attr "mode" "<MODE>")])
3970
3971 (define_insn "mov_<store>r"
3972 [(set (match_operand:BLK 0 "memory_operand" "+m")
3973 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3974 (match_operand:QI 2 "memory_operand" "m")
3975 (match_dup 0)]
3976 UNSPEC_STORE_RIGHT))]
3977 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3978 "<store>r\t%z1,%2"
3979 [(set_attr "move_type" "store")
3980 (set_attr "mode" "<MODE>")])
3981
3982 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
3983 ;; The required value is:
3984 ;;
3985 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3986 ;;
3987 ;; which translates to:
3988 ;;
3989 ;; lui op0,%highest(op1)
3990 ;; daddiu op0,op0,%higher(op1)
3991 ;; dsll op0,op0,16
3992 ;; daddiu op0,op0,%hi(op1)
3993 ;; dsll op0,op0,16
3994 ;;
3995 ;; The split is deferred until after flow2 to allow the peephole2 below
3996 ;; to take effect.
3997 (define_insn_and_split "*lea_high64"
3998 [(set (match_operand:DI 0 "register_operand" "=d")
3999 (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))]
4000 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4001 "#"
4002 "&& epilogue_completed"
4003 [(set (match_dup 0) (high:DI (match_dup 2)))
4004 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
4005 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
4006 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4007 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
4008 {
4009 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4010 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
4011 }
4012 [(set_attr "length" "20")])
4013
4014 ;; Use a scratch register to reduce the latency of the above pattern
4015 ;; on superscalar machines. The optimized sequence is:
4016 ;;
4017 ;; lui op1,%highest(op2)
4018 ;; lui op0,%hi(op2)
4019 ;; daddiu op1,op1,%higher(op2)
4020 ;; dsll32 op1,op1,0
4021 ;; daddu op1,op1,op0
4022 (define_peephole2
4023 [(set (match_operand:DI 1 "d_operand")
4024 (high:DI (match_operand:DI 2 "absolute_symbolic_operand")))
4025 (match_scratch:DI 0 "d")]
4026 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
4027 [(set (match_dup 1) (high:DI (match_dup 3)))
4028 (set (match_dup 0) (high:DI (match_dup 4)))
4029 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
4030 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
4031 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
4032 {
4033 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
4034 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
4035 })
4036
4037 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
4038 ;; SYMBOL_ABSOLUTE X will take 6 cycles. This next pattern allows combine
4039 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
4040 ;; used once. We can then use the sequence:
4041 ;;
4042 ;; lui op0,%highest(op1)
4043 ;; lui op2,%hi(op1)
4044 ;; daddiu op0,op0,%higher(op1)
4045 ;; daddiu op2,op2,%lo(op1)
4046 ;; dsll32 op0,op0,0
4047 ;; daddu op0,op0,op2
4048 ;;
4049 ;; which takes 4 cycles on most superscalar targets.
4050 (define_insn_and_split "*lea64"
4051 [(set (match_operand:DI 0 "register_operand" "=d")
4052 (match_operand:DI 1 "absolute_symbolic_operand" ""))
4053 (clobber (match_scratch:DI 2 "=&d"))]
4054 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
4055 "#"
4056 "&& reload_completed"
4057 [(set (match_dup 0) (high:DI (match_dup 3)))
4058 (set (match_dup 2) (high:DI (match_dup 4)))
4059 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
4060 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
4061 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
4062 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
4063 {
4064 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
4065 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
4066 }
4067 [(set_attr "length" "24")])
4068
4069 ;; Split HIGHs into:
4070 ;;
4071 ;; li op0,%hi(sym)
4072 ;; sll op0,16
4073 ;;
4074 ;; on MIPS16 targets.
4075 (define_split
4076 [(set (match_operand:P 0 "d_operand")
4077 (high:P (match_operand:P 1 "symbolic_operand_with_high")))]
4078 "TARGET_MIPS16 && reload_completed"
4079 [(set (match_dup 0) (unspec:P [(match_dup 1)] UNSPEC_UNSHIFTED_HIGH))
4080 (set (match_dup 0) (ashift:P (match_dup 0) (const_int 16)))])
4081
4082 (define_insn "*unshifted_high"
4083 [(set (match_operand:P 0 "d_operand" "=d")
4084 (unspec:P [(match_operand:P 1 "symbolic_operand_with_high")]
4085 UNSPEC_UNSHIFTED_HIGH))]
4086 ""
4087 "li\t%0,%h1"
4088 [(set_attr "extended_mips16" "yes")])
4089
4090 ;; Insns to fetch a symbol from a big GOT.
4091
4092 (define_insn_and_split "*xgot_hi<mode>"
4093 [(set (match_operand:P 0 "register_operand" "=d")
4094 (high:P (match_operand:P 1 "got_disp_operand" "")))]
4095 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4096 "#"
4097 "&& reload_completed"
4098 [(set (match_dup 0) (high:P (match_dup 2)))
4099 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
4100 {
4101 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
4102 operands[3] = pic_offset_table_rtx;
4103 }
4104 [(set_attr "got" "xgot_high")
4105 (set_attr "mode" "<MODE>")])
4106
4107 (define_insn_and_split "*xgot_lo<mode>"
4108 [(set (match_operand:P 0 "register_operand" "=d")
4109 (lo_sum:P (match_operand:P 1 "register_operand" "d")
4110 (match_operand:P 2 "got_disp_operand" "")))]
4111 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
4112 "#"
4113 "&& reload_completed"
4114 [(set (match_dup 0)
4115 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
4116 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
4117 [(set_attr "got" "load")
4118 (set_attr "mode" "<MODE>")])
4119
4120 ;; Insns to fetch a symbol from a normal GOT.
4121
4122 (define_insn_and_split "*got_disp<mode>"
4123 [(set (match_operand:P 0 "register_operand" "=d")
4124 (match_operand:P 1 "got_disp_operand" ""))]
4125 "TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
4126 "#"
4127 "&& reload_completed"
4128 [(set (match_dup 0) (match_dup 2))]
4129 { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
4130 [(set_attr "got" "load")
4131 (set_attr "mode" "<MODE>")])
4132
4133 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
4134
4135 (define_insn_and_split "*got_page<mode>"
4136 [(set (match_operand:P 0 "register_operand" "=d")
4137 (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
4138 "TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]"
4139 "#"
4140 "&& reload_completed"
4141 [(set (match_dup 0) (match_dup 2))]
4142 { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); }
4143 [(set_attr "got" "load")
4144 (set_attr "mode" "<MODE>")])
4145
4146 ;; Convenience expander that generates the rhs of a load_got<mode> insn.
4147 (define_expand "unspec_got_<mode>"
4148 [(unspec:P [(match_operand:P 0)
4149 (match_operand:P 1)] UNSPEC_LOAD_GOT)])
4150
4151 ;; Lower-level instructions for loading an address from the GOT.
4152 ;; We could use MEMs, but an unspec gives more optimization
4153 ;; opportunities.
4154
4155 (define_insn "load_got<mode>"
4156 [(set (match_operand:P 0 "register_operand" "=d")
4157 (unspec:P [(match_operand:P 1 "register_operand" "d")
4158 (match_operand:P 2 "immediate_operand" "")]
4159 UNSPEC_LOAD_GOT))]
4160 ""
4161 "<load>\t%0,%R2(%1)"
4162 [(set_attr "got" "load")
4163 (set_attr "mode" "<MODE>")])
4164
4165 ;; Instructions for adding the low 16 bits of an address to a register.
4166 ;; Operand 2 is the address: mips_print_operand works out which relocation
4167 ;; should be applied.
4168
4169 (define_insn "*low<mode>"
4170 [(set (match_operand:P 0 "register_operand" "=d")
4171 (lo_sum:P (match_operand:P 1 "register_operand" "d")
4172 (match_operand:P 2 "immediate_operand" "")))]
4173 "!TARGET_MIPS16"
4174 "<d>addiu\t%0,%1,%R2"
4175 [(set_attr "alu_type" "add")
4176 (set_attr "mode" "<MODE>")])
4177
4178 (define_insn "*low<mode>_mips16"
4179 [(set (match_operand:P 0 "register_operand" "=d")
4180 (lo_sum:P (match_operand:P 1 "register_operand" "0")
4181 (match_operand:P 2 "immediate_operand" "")))]
4182 "TARGET_MIPS16"
4183 "<d>addiu\t%0,%R2"
4184 [(set_attr "alu_type" "add")
4185 (set_attr "mode" "<MODE>")
4186 (set_attr "extended_mips16" "yes")])
4187
4188 ;; Expose MIPS16 uses of the global pointer after reload if the function
4189 ;; is responsible for setting up the register itself.
4190 (define_split
4191 [(set (match_operand:GPR 0 "d_operand")
4192 (const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))]
4193 "TARGET_MIPS16 && TARGET_USE_GOT && reload_completed"
4194 [(set (match_dup 0) (match_dup 1))]
4195 { operands[1] = pic_offset_table_rtx; })
4196
4197 ;; Allow combine to split complex const_int load sequences, using operand 2
4198 ;; to store the intermediate results. See move_operand for details.
4199 (define_split
4200 [(set (match_operand:GPR 0 "register_operand")
4201 (match_operand:GPR 1 "splittable_const_int_operand"))
4202 (clobber (match_operand:GPR 2 "register_operand"))]
4203 ""
4204 [(const_int 0)]
4205 {
4206 mips_move_integer (operands[2], operands[0], INTVAL (operands[1]));
4207 DONE;
4208 })
4209
4210 ;; Likewise, for symbolic operands.
4211 (define_split
4212 [(set (match_operand:P 0 "register_operand")
4213 (match_operand:P 1))
4214 (clobber (match_operand:P 2 "register_operand"))]
4215 "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
4216 [(set (match_dup 0) (match_dup 3))]
4217 {
4218 mips_split_symbol (operands[2], operands[1],
4219 MAX_MACHINE_MODE, &operands[3]);
4220 })
4221
4222 ;; 64-bit integer moves
4223
4224 ;; Unlike most other insns, the move insns can't be split with
4225 ;; different predicates, because register spilling and other parts of
4226 ;; the compiler, have memoized the insn number already.
4227
4228 (define_expand "movdi"
4229 [(set (match_operand:DI 0 "")
4230 (match_operand:DI 1 ""))]
4231 ""
4232 {
4233 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4234 DONE;
4235 })
4236
4237 ;; For mips16, we need a special case to handle storing $31 into
4238 ;; memory, since we don't have a constraint to match $31. This
4239 ;; instruction can be generated by save_restore_insns.
4240
4241 (define_insn "*mov<mode>_ra"
4242 [(set (match_operand:GPR 0 "stack_operand" "=m")
4243 (reg:GPR RETURN_ADDR_REGNUM))]
4244 "TARGET_MIPS16"
4245 "<store>\t$31,%0"
4246 [(set_attr "move_type" "store")
4247 (set_attr "mode" "<MODE>")])
4248
4249 (define_insn "*movdi_32bit"
4250 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m")
4251 (match_operand:DI 1 "move_operand" "d,i,m,d,*J,*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))]
4252 "!TARGET_64BIT && !TARGET_MIPS16
4253 && (register_operand (operands[0], DImode)
4254 || reg_or_0_operand (operands[1], DImode))"
4255 { return mips_output_move (operands[0], operands[1]); }
4256 [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
4257 (set (attr "mode")
4258 (if_then_else (eq_attr "move_type" "imul")
4259 (const_string "SI")
4260 (const_string "DI")))])
4261
4262 (define_insn "*movdi_32bit_mips16"
4263 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4264 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4265 "!TARGET_64BIT && TARGET_MIPS16
4266 && (register_operand (operands[0], DImode)
4267 || register_operand (operands[1], DImode))"
4268 { return mips_output_move (operands[0], operands[1]); }
4269 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4270 (set_attr "mode" "DI")])
4271
4272 (define_insn "*movdi_64bit"
4273 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*a,*d,*B*C*D,*B*C*D,*d,*m")
4274 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
4275 "TARGET_64BIT && !TARGET_MIPS16
4276 && (register_operand (operands[0], DImode)
4277 || reg_or_0_operand (operands[1], DImode))"
4278 { return mips_output_move (operands[0], operands[1]); }
4279 [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mtlo,mflo,mtc,fpload,mfc,fpstore")
4280 (set_attr "mode" "DI")])
4281
4282 (define_insn "*movdi_64bit_mips16"
4283 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4284 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,kf,m,d,*a"))]
4285 "TARGET_64BIT && TARGET_MIPS16
4286 && (register_operand (operands[0], DImode)
4287 || register_operand (operands[1], DImode))"
4288 { return mips_output_move (operands[0], operands[1]); }
4289 [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4290 (set_attr "mode" "DI")])
4291
4292 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4293 ;; when the original load is a 4 byte instruction but the add and the
4294 ;; load are 2 2 byte instructions.
4295
4296 (define_split
4297 [(set (match_operand:DI 0 "d_operand")
4298 (mem:DI (plus:DI (match_dup 0)
4299 (match_operand:DI 1 "const_int_operand"))))]
4300 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4301 && !TARGET_DEBUG_D_MODE
4302 && ((INTVAL (operands[1]) < 0
4303 && INTVAL (operands[1]) >= -0x10)
4304 || (INTVAL (operands[1]) >= 32 * 8
4305 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4306 || (INTVAL (operands[1]) >= 0
4307 && INTVAL (operands[1]) < 32 * 8
4308 && (INTVAL (operands[1]) & 7) != 0))"
4309 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4310 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4311 {
4312 HOST_WIDE_INT val = INTVAL (operands[1]);
4313
4314 if (val < 0)
4315 operands[2] = const0_rtx;
4316 else if (val >= 32 * 8)
4317 {
4318 int off = val & 7;
4319
4320 operands[1] = GEN_INT (0x8 + off);
4321 operands[2] = GEN_INT (val - off - 0x8);
4322 }
4323 else
4324 {
4325 int off = val & 7;
4326
4327 operands[1] = GEN_INT (off);
4328 operands[2] = GEN_INT (val - off);
4329 }
4330 })
4331
4332 ;; 32-bit Integer moves
4333
4334 ;; Unlike most other insns, the move insns can't be split with
4335 ;; different predicates, because register spilling and other parts of
4336 ;; the compiler, have memoized the insn number already.
4337
4338 (define_expand "mov<mode>"
4339 [(set (match_operand:IMOVE32 0 "")
4340 (match_operand:IMOVE32 1 ""))]
4341 ""
4342 {
4343 if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
4344 DONE;
4345 })
4346
4347 ;; The difference between these two is whether or not ints are allowed
4348 ;; in FP registers (off by default, use -mdebugh to enable).
4349
4350 (define_insn "*mov<mode>_internal"
4351 [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
4352 (match_operand:IMOVE32 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
4353 "!TARGET_MIPS16
4354 && (register_operand (operands[0], <MODE>mode)
4355 || reg_or_0_operand (operands[1], <MODE>mode))"
4356 { return mips_output_move (operands[0], operands[1]); }
4357 [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore")
4358 (set_attr "mode" "SI")])
4359
4360 (define_insn "*mov<mode>_mips16"
4361 [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d")
4362 (match_operand:IMOVE32 1 "move_operand" "d,d,y,K,N,U,kf,m,d,*a"))]
4363 "TARGET_MIPS16
4364 && (register_operand (operands[0], <MODE>mode)
4365 || register_operand (operands[1], <MODE>mode))"
4366 { return mips_output_move (operands[0], operands[1]); }
4367 [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mflo")
4368 (set_attr "mode" "SI")])
4369
4370 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4371 ;; when the original load is a 4 byte instruction but the add and the
4372 ;; load are 2 2 byte instructions.
4373
4374 (define_split
4375 [(set (match_operand:SI 0 "d_operand")
4376 (mem:SI (plus:SI (match_dup 0)
4377 (match_operand:SI 1 "const_int_operand"))))]
4378 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4379 && ((INTVAL (operands[1]) < 0
4380 && INTVAL (operands[1]) >= -0x80)
4381 || (INTVAL (operands[1]) >= 32 * 4
4382 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4383 || (INTVAL (operands[1]) >= 0
4384 && INTVAL (operands[1]) < 32 * 4
4385 && (INTVAL (operands[1]) & 3) != 0))"
4386 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4387 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4388 {
4389 HOST_WIDE_INT val = INTVAL (operands[1]);
4390
4391 if (val < 0)
4392 operands[2] = const0_rtx;
4393 else if (val >= 32 * 4)
4394 {
4395 int off = val & 3;
4396
4397 operands[1] = GEN_INT (0x7c + off);
4398 operands[2] = GEN_INT (val - off - 0x7c);
4399 }
4400 else
4401 {
4402 int off = val & 3;
4403
4404 operands[1] = GEN_INT (off);
4405 operands[2] = GEN_INT (val - off);
4406 }
4407 })
4408
4409 ;; On the mips16, we can split a load of certain constants into a load
4410 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4411 ;; instructions.
4412
4413 (define_split
4414 [(set (match_operand:SI 0 "d_operand")
4415 (match_operand:SI 1 "const_int_operand"))]
4416 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4417 && INTVAL (operands[1]) >= 0x100
4418 && INTVAL (operands[1]) <= 0xff + 0x7f"
4419 [(set (match_dup 0) (match_dup 1))
4420 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4421 {
4422 int val = INTVAL (operands[1]);
4423
4424 operands[1] = GEN_INT (0xff);
4425 operands[2] = GEN_INT (val - 0xff);
4426 })
4427
4428 ;; MIPS4 supports loading and storing a floating point register from
4429 ;; the sum of two general registers. We use two versions for each of
4430 ;; these four instructions: one where the two general registers are
4431 ;; SImode, and one where they are DImode. This is because general
4432 ;; registers will be in SImode when they hold 32-bit values, but,
4433 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
4434 ;; instructions will still work correctly.
4435
4436 ;; ??? Perhaps it would be better to support these instructions by
4437 ;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends. However, since
4438 ;; these instructions can only be used to load and store floating
4439 ;; point registers, that would probably cause trouble in reload.
4440
4441 (define_insn "*<ANYF:loadx>_<P:mode>"
4442 [(set (match_operand:ANYF 0 "register_operand" "=f")
4443 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4444 (match_operand:P 2 "register_operand" "d"))))]
4445 "ISA_HAS_FP4"
4446 "<ANYF:loadx>\t%0,%1(%2)"
4447 [(set_attr "type" "fpidxload")
4448 (set_attr "mode" "<ANYF:UNITMODE>")])
4449
4450 (define_insn "*<ANYF:storex>_<P:mode>"
4451 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
4452 (match_operand:P 2 "register_operand" "d")))
4453 (match_operand:ANYF 0 "register_operand" "f"))]
4454 "ISA_HAS_FP4"
4455 "<ANYF:storex>\t%0,%1(%2)"
4456 [(set_attr "type" "fpidxstore")
4457 (set_attr "mode" "<ANYF:UNITMODE>")])
4458
4459 ;; Scaled indexed address load.
4460 ;; Per md.texi, we only need to look for a pattern with multiply in the
4461 ;; address expression, not shift.
4462
4463 (define_insn "*lwxs"
4464 [(set (match_operand:IMOVE32 0 "register_operand" "=d")
4465 (mem:IMOVE32
4466 (plus:P (mult:P (match_operand:P 1 "register_operand" "d")
4467 (const_int 4))
4468 (match_operand:P 2 "register_operand" "d"))))]
4469 "ISA_HAS_LWXS"
4470 "lwxs\t%0,%1(%2)"
4471 [(set_attr "type" "load")
4472 (set_attr "mode" "SI")])
4473
4474 ;; 16-bit Integer moves
4475
4476 ;; Unlike most other insns, the move insns can't be split with
4477 ;; different predicates, because register spilling and other parts of
4478 ;; the compiler, have memoized the insn number already.
4479 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4480
4481 (define_expand "movhi"
4482 [(set (match_operand:HI 0 "")
4483 (match_operand:HI 1 ""))]
4484 ""
4485 {
4486 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4487 DONE;
4488 })
4489
4490 (define_insn "*movhi_internal"
4491 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d")
4492 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*d*J,*a"))]
4493 "!TARGET_MIPS16
4494 && (register_operand (operands[0], HImode)
4495 || reg_or_0_operand (operands[1], HImode))"
4496 { return mips_output_move (operands[0], operands[1]); }
4497 [(set_attr "move_type" "move,const,load,store,mtlo,mflo")
4498 (set_attr "mode" "HI")])
4499
4500 (define_insn "*movhi_mips16"
4501 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4502 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4503 "TARGET_MIPS16
4504 && (register_operand (operands[0], HImode)
4505 || register_operand (operands[1], HImode))"
4506 { return mips_output_move (operands[0], operands[1]); }
4507 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4508 (set_attr "mode" "HI")])
4509
4510 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4511 ;; when the original load is a 4 byte instruction but the add and the
4512 ;; load are 2 2 byte instructions.
4513
4514 (define_split
4515 [(set (match_operand:HI 0 "d_operand")
4516 (mem:HI (plus:SI (match_dup 0)
4517 (match_operand:SI 1 "const_int_operand"))))]
4518 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4519 && ((INTVAL (operands[1]) < 0
4520 && INTVAL (operands[1]) >= -0x80)
4521 || (INTVAL (operands[1]) >= 32 * 2
4522 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4523 || (INTVAL (operands[1]) >= 0
4524 && INTVAL (operands[1]) < 32 * 2
4525 && (INTVAL (operands[1]) & 1) != 0))"
4526 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4527 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4528 {
4529 HOST_WIDE_INT val = INTVAL (operands[1]);
4530
4531 if (val < 0)
4532 operands[2] = const0_rtx;
4533 else if (val >= 32 * 2)
4534 {
4535 int off = val & 1;
4536
4537 operands[1] = GEN_INT (0x7e + off);
4538 operands[2] = GEN_INT (val - off - 0x7e);
4539 }
4540 else
4541 {
4542 int off = val & 1;
4543
4544 operands[1] = GEN_INT (off);
4545 operands[2] = GEN_INT (val - off);
4546 }
4547 })
4548
4549 ;; 8-bit Integer moves
4550
4551 ;; Unlike most other insns, the move insns can't be split with
4552 ;; different predicates, because register spilling and other parts of
4553 ;; the compiler, have memoized the insn number already.
4554 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4555
4556 (define_expand "movqi"
4557 [(set (match_operand:QI 0 "")
4558 (match_operand:QI 1 ""))]
4559 ""
4560 {
4561 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4562 DONE;
4563 })
4564
4565 (define_insn "*movqi_internal"
4566 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d")
4567 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*d*J,*a"))]
4568 "!TARGET_MIPS16
4569 && (register_operand (operands[0], QImode)
4570 || reg_or_0_operand (operands[1], QImode))"
4571 { return mips_output_move (operands[0], operands[1]); }
4572 [(set_attr "move_type" "move,const,load,store,mtlo,mflo")
4573 (set_attr "mode" "QI")])
4574
4575 (define_insn "*movqi_mips16"
4576 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4577 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4578 "TARGET_MIPS16
4579 && (register_operand (operands[0], QImode)
4580 || register_operand (operands[1], QImode))"
4581 { return mips_output_move (operands[0], operands[1]); }
4582 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4583 (set_attr "mode" "QI")])
4584
4585 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4586 ;; when the original load is a 4 byte instruction but the add and the
4587 ;; load are 2 2 byte instructions.
4588
4589 (define_split
4590 [(set (match_operand:QI 0 "d_operand")
4591 (mem:QI (plus:SI (match_dup 0)
4592 (match_operand:SI 1 "const_int_operand"))))]
4593 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4594 && ((INTVAL (operands[1]) < 0
4595 && INTVAL (operands[1]) >= -0x80)
4596 || (INTVAL (operands[1]) >= 32
4597 && INTVAL (operands[1]) <= 31 + 0x7f))"
4598 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4599 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4600 {
4601 HOST_WIDE_INT val = INTVAL (operands[1]);
4602
4603 if (val < 0)
4604 operands[2] = const0_rtx;
4605 else
4606 {
4607 operands[1] = GEN_INT (0x7f);
4608 operands[2] = GEN_INT (val - 0x7f);
4609 }
4610 })
4611
4612 ;; 32-bit floating point moves
4613
4614 (define_expand "movsf"
4615 [(set (match_operand:SF 0 "")
4616 (match_operand:SF 1 ""))]
4617 ""
4618 {
4619 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4620 DONE;
4621 })
4622
4623 (define_insn "*movsf_hardfloat"
4624 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4625 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
4626 "TARGET_HARD_FLOAT
4627 && (register_operand (operands[0], SFmode)
4628 || reg_or_0_operand (operands[1], SFmode))"
4629 { return mips_output_move (operands[0], operands[1]); }
4630 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4631 (set_attr "mode" "SF")])
4632
4633 (define_insn "*movsf_softfloat"
4634 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4635 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4636 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4637 && (register_operand (operands[0], SFmode)
4638 || reg_or_0_operand (operands[1], SFmode))"
4639 { return mips_output_move (operands[0], operands[1]); }
4640 [(set_attr "move_type" "move,load,store")
4641 (set_attr "mode" "SF")])
4642
4643 (define_insn "*movsf_mips16"
4644 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4645 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4646 "TARGET_MIPS16
4647 && (register_operand (operands[0], SFmode)
4648 || register_operand (operands[1], SFmode))"
4649 { return mips_output_move (operands[0], operands[1]); }
4650 [(set_attr "move_type" "move,move,move,load,store")
4651 (set_attr "mode" "SF")])
4652
4653 ;; 64-bit floating point moves
4654
4655 (define_expand "movdf"
4656 [(set (match_operand:DF 0 "")
4657 (match_operand:DF 1 ""))]
4658 ""
4659 {
4660 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4661 DONE;
4662 })
4663
4664 (define_insn "*movdf_hardfloat"
4665 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4666 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
4667 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
4668 && (register_operand (operands[0], DFmode)
4669 || reg_or_0_operand (operands[1], DFmode))"
4670 { return mips_output_move (operands[0], operands[1]); }
4671 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4672 (set_attr "mode" "DF")])
4673
4674 (define_insn "*movdf_softfloat"
4675 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m")
4676 (match_operand:DF 1 "move_operand" "dG,m,dG"))]
4677 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4678 && (register_operand (operands[0], DFmode)
4679 || reg_or_0_operand (operands[1], DFmode))"
4680 { return mips_output_move (operands[0], operands[1]); }
4681 [(set_attr "move_type" "move,load,store")
4682 (set_attr "mode" "DF")])
4683
4684 (define_insn "*movdf_mips16"
4685 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4686 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4687 "TARGET_MIPS16
4688 && (register_operand (operands[0], DFmode)
4689 || register_operand (operands[1], DFmode))"
4690 { return mips_output_move (operands[0], operands[1]); }
4691 [(set_attr "move_type" "move,move,move,load,store")
4692 (set_attr "mode" "DF")])
4693
4694 ;; 128-bit integer moves
4695
4696 (define_expand "movti"
4697 [(set (match_operand:TI 0)
4698 (match_operand:TI 1))]
4699 "TARGET_64BIT"
4700 {
4701 if (mips_legitimize_move (TImode, operands[0], operands[1]))
4702 DONE;
4703 })
4704
4705 (define_insn "*movti"
4706 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d")
4707 (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))]
4708 "TARGET_64BIT
4709 && !TARGET_MIPS16
4710 && (register_operand (operands[0], TImode)
4711 || reg_or_0_operand (operands[1], TImode))"
4712 { return mips_output_move (operands[0], operands[1]); }
4713 [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo")
4714 (set (attr "mode")
4715 (if_then_else (eq_attr "move_type" "imul")
4716 (const_string "SI")
4717 (const_string "TI")))])
4718
4719 (define_insn "*movti_mips16"
4720 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4721 (match_operand:TI 1 "move_operand" "d,d,y,K,N,m,d,*a"))]
4722 "TARGET_64BIT
4723 && TARGET_MIPS16
4724 && (register_operand (operands[0], TImode)
4725 || register_operand (operands[1], TImode))"
4726 "#"
4727 [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
4728 (set_attr "mode" "TI")])
4729
4730 ;; 128-bit floating point moves
4731
4732 (define_expand "movtf"
4733 [(set (match_operand:TF 0)
4734 (match_operand:TF 1))]
4735 "TARGET_64BIT"
4736 {
4737 if (mips_legitimize_move (TFmode, operands[0], operands[1]))
4738 DONE;
4739 })
4740
4741 ;; This pattern handles both hard- and soft-float cases.
4742 (define_insn "*movtf"
4743 [(set (match_operand:TF 0 "nonimmediate_operand" "=d,d,m,f,d,f,m")
4744 (match_operand:TF 1 "move_operand" "dG,m,dG,dG,f,m,f"))]
4745 "TARGET_64BIT
4746 && !TARGET_MIPS16
4747 && (register_operand (operands[0], TFmode)
4748 || reg_or_0_operand (operands[1], TFmode))"
4749 "#"
4750 [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore")
4751 (set_attr "mode" "TF")])
4752
4753 (define_insn "*movtf_mips16"
4754 [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m")
4755 (match_operand:TF 1 "move_operand" "d,d,y,m,d"))]
4756 "TARGET_64BIT
4757 && TARGET_MIPS16
4758 && (register_operand (operands[0], TFmode)
4759 || register_operand (operands[1], TFmode))"
4760 "#"
4761 [(set_attr "move_type" "move,move,move,load,store")
4762 (set_attr "mode" "TF")])
4763
4764 (define_split
4765 [(set (match_operand:MOVE64 0 "nonimmediate_operand")
4766 (match_operand:MOVE64 1 "move_operand"))]
4767 "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4768 [(const_int 0)]
4769 {
4770 mips_split_move_insn (operands[0], operands[1], curr_insn);
4771 DONE;
4772 })
4773
4774 (define_split
4775 [(set (match_operand:MOVE128 0 "nonimmediate_operand")
4776 (match_operand:MOVE128 1 "move_operand"))]
4777 "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
4778 [(const_int 0)]
4779 {
4780 mips_split_move_insn (operands[0], operands[1], curr_insn);
4781 DONE;
4782 })
4783
4784 ;; When generating mips16 code, split moves of negative constants into
4785 ;; a positive "li" followed by a negation.
4786 (define_split
4787 [(set (match_operand 0 "d_operand")
4788 (match_operand 1 "const_int_operand"))]
4789 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4790 [(set (match_dup 2)
4791 (match_dup 3))
4792 (set (match_dup 2)
4793 (neg:SI (match_dup 2)))]
4794 {
4795 operands[2] = gen_lowpart (SImode, operands[0]);
4796 operands[3] = GEN_INT (-INTVAL (operands[1]));
4797 })
4798
4799 ;; 64-bit paired-single floating point moves
4800
4801 (define_expand "movv2sf"
4802 [(set (match_operand:V2SF 0)
4803 (match_operand:V2SF 1))]
4804 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
4805 {
4806 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4807 DONE;
4808 })
4809
4810 (define_insn "*movv2sf"
4811 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4812 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4813 "TARGET_HARD_FLOAT
4814 && TARGET_PAIRED_SINGLE_FLOAT
4815 && (register_operand (operands[0], V2SFmode)
4816 || reg_or_0_operand (operands[1], V2SFmode))"
4817 { return mips_output_move (operands[0], operands[1]); }
4818 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4819 (set_attr "mode" "DF")])
4820
4821 ;; Extract the high part of a HI/LO value. See mips_hard_regno_mode_ok_p
4822 ;; for the reason why we can't just use (reg:GPR HI_REGNUM).
4823 ;;
4824 ;; When generating VR4120 or VR4130 code, we use MACCHI and DMACCHI
4825 ;; instead of MFHI. This avoids both the normal MIPS III hi/lo hazards
4826 ;; and the errata related to -mfix-vr4130.
4827 (define_insn "mfhi<GPR:mode>_<HILO:mode>"
4828 [(set (match_operand:GPR 0 "register_operand" "=d")
4829 (unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")]
4830 UNSPEC_MFHI))]
4831 ""
4832 { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; }
4833 [(set_attr "type" "mfhi")
4834 (set_attr "mode" "<GPR:MODE>")])
4835
4836 ;; Set the high part of a HI/LO value, given that the low part has
4837 ;; already been set. See mips_hard_regno_mode_ok_p for the reason
4838 ;; why we can't just use (reg:GPR HI_REGNUM).
4839 (define_insn "mthi<GPR:mode>_<HILO:mode>"
4840 [(set (match_operand:HILO 0 "register_operand" "=x")
4841 (unspec:HILO [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
4842 (match_operand:GPR 2 "register_operand" "l")]
4843 UNSPEC_MTHI))]
4844 ""
4845 "mthi\t%z1"
4846 [(set_attr "type" "mthi")
4847 (set_attr "mode" "SI")])
4848
4849 ;; Emit a doubleword move in which exactly one of the operands is
4850 ;; a floating-point register. We can't just emit two normal moves
4851 ;; because of the constraints imposed by the FPU register model;
4852 ;; see mips_cannot_change_mode_class for details. Instead, we keep
4853 ;; the FPR whole and use special patterns to refer to each word of
4854 ;; the other operand.
4855
4856 (define_expand "move_doubleword_fpr<mode>"
4857 [(set (match_operand:SPLITF 0)
4858 (match_operand:SPLITF 1))]
4859 ""
4860 {
4861 if (FP_REG_RTX_P (operands[0]))
4862 {
4863 rtx low = mips_subword (operands[1], 0);
4864 rtx high = mips_subword (operands[1], 1);
4865 emit_insn (gen_load_low<mode> (operands[0], low));
4866 if (TARGET_FLOAT64 && !TARGET_64BIT)
4867 emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
4868 else
4869 emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
4870 }
4871 else
4872 {
4873 rtx low = mips_subword (operands[0], 0);
4874 rtx high = mips_subword (operands[0], 1);
4875 emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
4876 if (TARGET_FLOAT64 && !TARGET_64BIT)
4877 emit_insn (gen_mfhc1<mode> (high, operands[1]));
4878 else
4879 emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
4880 }
4881 DONE;
4882 })
4883
4884 ;; Load the low word of operand 0 with operand 1.
4885 (define_insn "load_low<mode>"
4886 [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4887 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
4888 UNSPEC_LOAD_LOW))]
4889 "TARGET_HARD_FLOAT"
4890 {
4891 operands[0] = mips_subword (operands[0], 0);
4892 return mips_output_move (operands[0], operands[1]);
4893 }
4894 [(set_attr "move_type" "mtc,fpload")
4895 (set_attr "mode" "<HALFMODE>")])
4896
4897 ;; Load the high word of operand 0 from operand 1, preserving the value
4898 ;; in the low word.
4899 (define_insn "load_high<mode>"
4900 [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
4901 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
4902 (match_operand:SPLITF 2 "register_operand" "0,0")]
4903 UNSPEC_LOAD_HIGH))]
4904 "TARGET_HARD_FLOAT"
4905 {
4906 operands[0] = mips_subword (operands[0], 1);
4907 return mips_output_move (operands[0], operands[1]);
4908 }
4909 [(set_attr "move_type" "mtc,fpload")
4910 (set_attr "mode" "<HALFMODE>")])
4911
4912 ;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the
4913 ;; high word and 0 to store the low word.
4914 (define_insn "store_word<mode>"
4915 [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
4916 (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
4917 (match_operand 2 "const_int_operand")]
4918 UNSPEC_STORE_WORD))]
4919 "TARGET_HARD_FLOAT"
4920 {
4921 operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
4922 return mips_output_move (operands[0], operands[1]);
4923 }
4924 [(set_attr "move_type" "mfc,fpstore")
4925 (set_attr "mode" "<HALFMODE>")])
4926
4927 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
4928 ;; value in the low word.
4929 (define_insn "mthc1<mode>"
4930 [(set (match_operand:SPLITF 0 "register_operand" "=f")
4931 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "dJ")
4932 (match_operand:SPLITF 2 "register_operand" "0")]
4933 UNSPEC_MTHC1))]
4934 "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
4935 "mthc1\t%z1,%0"
4936 [(set_attr "move_type" "mtc")
4937 (set_attr "mode" "<HALFMODE>")])
4938
4939 ;; Move high word of operand 1 to operand 0 using mfhc1.
4940 (define_insn "mfhc1<mode>"
4941 [(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
4942 (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
4943 UNSPEC_MFHC1))]
4944 "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
4945 "mfhc1\t%0,%1"
4946 [(set_attr "move_type" "mfc")
4947 (set_attr "mode" "<HALFMODE>")])
4948
4949 ;; Move a constant that satisfies CONST_GP_P into operand 0.
4950 (define_expand "load_const_gp_<mode>"
4951 [(set (match_operand:P 0 "register_operand" "=d")
4952 (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
4953
4954 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4955 ;; of _gp from the start of this function. Operand 1 is the incoming
4956 ;; function address.
4957 (define_insn_and_split "loadgp_newabi_<mode>"
4958 [(set (match_operand:P 0 "register_operand" "=&d")
4959 (unspec:P [(match_operand:P 1)
4960 (match_operand:P 2 "register_operand" "d")]
4961 UNSPEC_LOADGP))]
4962 "mips_current_loadgp_style () == LOADGP_NEWABI"
4963 { return mips_must_initialize_gp_p () ? "#" : ""; }
4964 "&& mips_must_initialize_gp_p ()"
4965 [(set (match_dup 0) (match_dup 3))
4966 (set (match_dup 0) (match_dup 4))
4967 (set (match_dup 0) (match_dup 5))]
4968 {
4969 operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
4970 operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
4971 operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
4972 }
4973 [(set_attr "type" "ghost")])
4974
4975 ;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
4976 (define_insn_and_split "loadgp_absolute_<mode>"
4977 [(set (match_operand:P 0 "register_operand" "=d")
4978 (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))]
4979 "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4980 { return mips_must_initialize_gp_p () ? "#" : ""; }
4981 "&& mips_must_initialize_gp_p ()"
4982 [(const_int 0)]
4983 {
4984 mips_emit_move (operands[0], operands[1]);
4985 DONE;
4986 }
4987 [(set_attr "type" "ghost")])
4988
4989 ;; This blockage instruction prevents the gp load from being
4990 ;; scheduled after an implicit use of gp. It also prevents
4991 ;; the load from being deleted as dead.
4992 (define_insn "loadgp_blockage"
4993 [(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)]
4994 ""
4995 ""
4996 [(set_attr "type" "ghost")])
4997
4998 ;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol
4999 ;; and operand 1 is the __GOTT_INDEX__ symbol.
5000 (define_insn_and_split "loadgp_rtp_<mode>"
5001 [(set (match_operand:P 0 "register_operand" "=d")
5002 (unspec:P [(match_operand:P 1 "symbol_ref_operand")
5003 (match_operand:P 2 "symbol_ref_operand")]
5004 UNSPEC_LOADGP))]
5005 "mips_current_loadgp_style () == LOADGP_RTP"
5006 { return mips_must_initialize_gp_p () ? "#" : ""; }
5007 "&& mips_must_initialize_gp_p ()"
5008 [(set (match_dup 0) (high:P (match_dup 3)))
5009 (set (match_dup 0) (unspec:P [(match_dup 0)
5010 (match_dup 3)] UNSPEC_LOAD_GOT))
5011 (set (match_dup 0) (unspec:P [(match_dup 0)
5012 (match_dup 4)] UNSPEC_LOAD_GOT))]
5013 {
5014 operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
5015 operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
5016 }
5017 [(set_attr "type" "ghost")])
5018
5019 ;; Initialize the global pointer for MIPS16 code. Operand 0 is the
5020 ;; global pointer and operand 1 is the MIPS16 register that holds
5021 ;; the required value.
5022 (define_insn_and_split "copygp_mips16_<mode>"
5023 [(set (match_operand:P 0 "register_operand" "=y")
5024 (unspec:P [(match_operand:P 1 "register_operand" "d")]
5025 UNSPEC_COPYGP))]
5026 "TARGET_MIPS16"
5027 { return mips_must_initialize_gp_p () ? "#" : ""; }
5028 "&& mips_must_initialize_gp_p ()"
5029 [(set (match_dup 0) (match_dup 1))]
5030 ""
5031 [(set_attr "type" "ghost")])
5032
5033 ;; A placeholder for where the cprestore instruction should go,
5034 ;; if we decide we need one. Operand 0 and operand 1 are as for
5035 ;; "cprestore". Operand 2 is a register that holds the gp value.
5036 ;;
5037 ;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx,
5038 ;; otherwise any register that holds the correct value will do.
5039 (define_insn_and_split "potential_cprestore_<mode>"
5040 [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5041 (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5042 (match_operand:P 2 "register_operand" "d,d")]
5043 UNSPEC_POTENTIAL_CPRESTORE))
5044 (clobber (match_operand:P 3 "scratch_operand" "=X,&d"))]
5045 "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx"
5046 { return mips_must_initialize_gp_p () ? "#" : ""; }
5047 "mips_must_initialize_gp_p ()"
5048 [(const_int 0)]
5049 {
5050 mips_save_gp_to_cprestore_slot (operands[0], operands[1],
5051 operands[2], operands[3]);
5052 DONE;
5053 }
5054 [(set_attr "type" "ghost")])
5055
5056 ;; Emit a .cprestore directive, which normally expands to a single store
5057 ;; instruction. Operand 0 is a (possibly illegitimate) sp-based MEM
5058 ;; for the cprestore slot. Operand 1 is the offset of the slot from
5059 ;; the stack pointer. (This is redundant with operand 0, but it makes
5060 ;; things a little simpler.)
5061 (define_insn "cprestore_<mode>"
5062 [(set (match_operand:P 0 "cprestore_save_slot_operand" "=X,X")
5063 (unspec:P [(match_operand:P 1 "const_int_operand" "I,i")
5064 (reg:P 28)]
5065 UNSPEC_CPRESTORE))]
5066 "TARGET_CPRESTORE_DIRECTIVE"
5067 {
5068 if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
5069 return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
5070 else
5071 return ".cprestore\t%1";
5072 }
5073 [(set_attr "type" "store")
5074 (set_attr "length" "4,12")])
5075
5076 (define_insn "use_cprestore_<mode>"
5077 [(set (reg:P CPRESTORE_SLOT_REGNUM)
5078 (match_operand:P 0 "cprestore_load_slot_operand"))]
5079 ""
5080 ""
5081 [(set_attr "type" "ghost")])
5082
5083 ;; Expand in-line code to clear the instruction cache between operand[0] and
5084 ;; operand[1].
5085 (define_expand "clear_cache"
5086 [(match_operand 0 "pmode_register_operand")
5087 (match_operand 1 "pmode_register_operand")]
5088 ""
5089 "
5090 {
5091 if (TARGET_SYNCI)
5092 {
5093 mips_expand_synci_loop (operands[0], operands[1]);
5094 emit_insn (gen_sync ());
5095 emit_insn (PMODE_INSN (gen_clear_hazard, ()));
5096 }
5097 else if (mips_cache_flush_func && mips_cache_flush_func[0])
5098 {
5099 rtx len = gen_reg_rtx (Pmode);
5100 emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
5101 MIPS_ICACHE_SYNC (operands[0], len);
5102 }
5103 DONE;
5104 }")
5105
5106 (define_insn "sync"
5107 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
5108 "GENERATE_SYNC"
5109 { return mips_output_sync (); })
5110
5111 (define_insn "synci"
5112 [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
5113 UNSPEC_SYNCI)]
5114 "TARGET_SYNCI"
5115 "synci\t0(%0)")
5116
5117 (define_insn "rdhwr_synci_step_<mode>"
5118 [(set (match_operand:P 0 "register_operand" "=d")
5119 (unspec_volatile [(const_int 1)]
5120 UNSPEC_RDHWR))]
5121 "ISA_HAS_SYNCI"
5122 "rdhwr\t%0,$1")
5123
5124 (define_insn "clear_hazard_<mode>"
5125 [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
5126 (clobber (reg:P RETURN_ADDR_REGNUM))]
5127 "ISA_HAS_SYNCI"
5128 {
5129 return "%(%<bal\t1f\n"
5130 "\tnop\n"
5131 "1:\t<d>addiu\t$31,$31,12\n"
5132 "\tjr.hb\t$31\n"
5133 "\tnop%>%)";
5134 }
5135 [(set_attr "length" "20")])
5136
5137 ;; Cache operations for R4000-style caches.
5138 (define_insn "mips_cache"
5139 [(set (mem:BLK (scratch))
5140 (unspec:BLK [(match_operand:SI 0 "const_int_operand")
5141 (match_operand:QI 1 "address_operand" "p")]
5142 UNSPEC_MIPS_CACHE))]
5143 "ISA_HAS_CACHE"
5144 "cache\t%X0,%a1")
5145
5146 ;; Similar, but with the operands hard-coded to an R10K cache barrier
5147 ;; operation. We keep the pattern distinct so that we can identify
5148 ;; cache operations inserted by -mr10k-cache-barrier=, and so that
5149 ;; the operation is never inserted into a delay slot.
5150 (define_insn "r10k_cache_barrier"
5151 [(set (mem:BLK (scratch))
5152 (unspec:BLK [(const_int 0)] UNSPEC_R10K_CACHE_BARRIER))]
5153 "ISA_HAS_CACHE"
5154 "cache\t0x14,0(%$)"
5155 [(set_attr "can_delay" "no")])
5156 \f
5157 ;; Block moves, see mips.c for more details.
5158 ;; Argument 0 is the destination
5159 ;; Argument 1 is the source
5160 ;; Argument 2 is the length
5161 ;; Argument 3 is the alignment
5162
5163 (define_expand "movmemsi"
5164 [(parallel [(set (match_operand:BLK 0 "general_operand")
5165 (match_operand:BLK 1 "general_operand"))
5166 (use (match_operand:SI 2 ""))
5167 (use (match_operand:SI 3 "const_int_operand"))])]
5168 "!TARGET_MIPS16 && !TARGET_MEMCPY"
5169 {
5170 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5171 DONE;
5172 else
5173 FAIL;
5174 })
5175 \f
5176 ;;
5177 ;; ....................
5178 ;;
5179 ;; SHIFTS
5180 ;;
5181 ;; ....................
5182
5183 (define_expand "<optab><mode>3"
5184 [(set (match_operand:GPR 0 "register_operand")
5185 (any_shift:GPR (match_operand:GPR 1 "register_operand")
5186 (match_operand:SI 2 "arith_operand")))]
5187 ""
5188 {
5189 /* On the mips16, a shift of more than 8 is a four byte instruction,
5190 so, for a shift between 8 and 16, it is just as fast to do two
5191 shifts of 8 or less. If there is a lot of shifting going on, we
5192 may win in CSE. Otherwise combine will put the shifts back
5193 together again. This can be called by mips_function_arg, so we must
5194 be careful not to allocate a new register if we've reached the
5195 reload pass. */
5196 if (TARGET_MIPS16
5197 && optimize
5198 && CONST_INT_P (operands[2])
5199 && INTVAL (operands[2]) > 8
5200 && INTVAL (operands[2]) <= 16
5201 && !reload_in_progress
5202 && !reload_completed)
5203 {
5204 rtx temp = gen_reg_rtx (<MODE>mode);
5205
5206 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
5207 emit_insn (gen_<optab><mode>3 (operands[0], temp,
5208 GEN_INT (INTVAL (operands[2]) - 8)));
5209 DONE;
5210 }
5211 })
5212
5213 (define_insn "*<optab><mode>3"
5214 [(set (match_operand:GPR 0 "register_operand" "=d")
5215 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
5216 (match_operand:SI 2 "arith_operand" "dI")))]
5217 "!TARGET_MIPS16"
5218 {
5219 if (CONST_INT_P (operands[2]))
5220 operands[2] = GEN_INT (INTVAL (operands[2])
5221 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
5222
5223 return "<d><insn>\t%0,%1,%2";
5224 }
5225 [(set_attr "type" "shift")
5226 (set_attr "mode" "<MODE>")])
5227
5228 (define_insn "*<optab>si3_extend"
5229 [(set (match_operand:DI 0 "register_operand" "=d")
5230 (sign_extend:DI
5231 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
5232 (match_operand:SI 2 "arith_operand" "dI"))))]
5233 "TARGET_64BIT && !TARGET_MIPS16"
5234 {
5235 if (CONST_INT_P (operands[2]))
5236 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5237
5238 return "<insn>\t%0,%1,%2";
5239 }
5240 [(set_attr "type" "shift")
5241 (set_attr "mode" "SI")])
5242
5243 (define_insn "*<optab>si3_mips16"
5244 [(set (match_operand:SI 0 "register_operand" "=d,d")
5245 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
5246 (match_operand:SI 2 "arith_operand" "d,I")))]
5247 "TARGET_MIPS16"
5248 {
5249 if (which_alternative == 0)
5250 return "<insn>\t%0,%2";
5251
5252 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5253 return "<insn>\t%0,%1,%2";
5254 }
5255 [(set_attr "type" "shift")
5256 (set_attr "mode" "SI")
5257 (set_attr_alternative "length"
5258 [(const_int 4)
5259 (if_then_else (match_operand 2 "m16_uimm3_b")
5260 (const_int 4)
5261 (const_int 8))])])
5262
5263 ;; We need separate DImode MIPS16 patterns because of the irregularity
5264 ;; of right shifts.
5265 (define_insn "*ashldi3_mips16"
5266 [(set (match_operand:DI 0 "register_operand" "=d,d")
5267 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5268 (match_operand:SI 2 "arith_operand" "d,I")))]
5269 "TARGET_64BIT && TARGET_MIPS16"
5270 {
5271 if (which_alternative == 0)
5272 return "dsll\t%0,%2";
5273
5274 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5275 return "dsll\t%0,%1,%2";
5276 }
5277 [(set_attr "type" "shift")
5278 (set_attr "mode" "DI")
5279 (set_attr_alternative "length"
5280 [(const_int 4)
5281 (if_then_else (match_operand 2 "m16_uimm3_b")
5282 (const_int 4)
5283 (const_int 8))])])
5284
5285 (define_insn "*ashrdi3_mips16"
5286 [(set (match_operand:DI 0 "register_operand" "=d,d")
5287 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5288 (match_operand:SI 2 "arith_operand" "d,I")))]
5289 "TARGET_64BIT && TARGET_MIPS16"
5290 {
5291 if (CONST_INT_P (operands[2]))
5292 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5293
5294 return "dsra\t%0,%2";
5295 }
5296 [(set_attr "type" "shift")
5297 (set_attr "mode" "DI")
5298 (set_attr_alternative "length"
5299 [(const_int 4)
5300 (if_then_else (match_operand 2 "m16_uimm3_b")
5301 (const_int 4)
5302 (const_int 8))])])
5303
5304 (define_insn "*lshrdi3_mips16"
5305 [(set (match_operand:DI 0 "register_operand" "=d,d")
5306 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5307 (match_operand:SI 2 "arith_operand" "d,I")))]
5308 "TARGET_64BIT && TARGET_MIPS16"
5309 {
5310 if (CONST_INT_P (operands[2]))
5311 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5312
5313 return "dsrl\t%0,%2";
5314 }
5315 [(set_attr "type" "shift")
5316 (set_attr "mode" "DI")
5317 (set_attr_alternative "length"
5318 [(const_int 4)
5319 (if_then_else (match_operand 2 "m16_uimm3_b")
5320 (const_int 4)
5321 (const_int 8))])])
5322
5323 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5324
5325 (define_split
5326 [(set (match_operand:GPR 0 "d_operand")
5327 (any_shift:GPR (match_operand:GPR 1 "d_operand")
5328 (match_operand:GPR 2 "const_int_operand")))]
5329 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5330 && INTVAL (operands[2]) > 8
5331 && INTVAL (operands[2]) <= 16"
5332 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
5333 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
5334 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5335
5336 ;; If we load a byte on the mips16 as a bitfield, the resulting
5337 ;; sequence of instructions is too complicated for combine, because it
5338 ;; involves four instructions: a load, a shift, a constant load into a
5339 ;; register, and an and (the key problem here is that the mips16 does
5340 ;; not have and immediate). We recognize a shift of a load in order
5341 ;; to make it simple enough for combine to understand.
5342 ;;
5343 ;; The length here is the worst case: the length of the split version
5344 ;; will be more accurate.
5345 (define_insn_and_split ""
5346 [(set (match_operand:SI 0 "register_operand" "=d")
5347 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5348 (match_operand:SI 2 "immediate_operand" "I")))]
5349 "TARGET_MIPS16"
5350 "#"
5351 ""
5352 [(set (match_dup 0) (match_dup 1))
5353 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5354 ""
5355 [(set_attr "type" "load")
5356 (set_attr "mode" "SI")
5357 (set_attr "length" "16")])
5358
5359 (define_insn "rotr<mode>3"
5360 [(set (match_operand:GPR 0 "register_operand" "=d")
5361 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
5362 (match_operand:SI 2 "arith_operand" "dI")))]
5363 "ISA_HAS_ROR"
5364 {
5365 if (CONST_INT_P (operands[2]))
5366 gcc_assert (INTVAL (operands[2]) >= 0
5367 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
5368
5369 return "<d>ror\t%0,%1,%2";
5370 }
5371 [(set_attr "type" "shift")
5372 (set_attr "mode" "<MODE>")])
5373 \f
5374 ;;
5375 ;; ....................
5376 ;;
5377 ;; CONDITIONAL BRANCHES
5378 ;;
5379 ;; ....................
5380
5381 ;; Conditional branches on floating-point equality tests.
5382
5383 (define_insn "*branch_fp"
5384 [(set (pc)
5385 (if_then_else
5386 (match_operator 1 "equality_operator"
5387 [(match_operand:CC 2 "register_operand" "z")
5388 (const_int 0)])
5389 (label_ref (match_operand 0 "" ""))
5390 (pc)))]
5391 "TARGET_HARD_FLOAT"
5392 {
5393 return mips_output_conditional_branch (insn, operands,
5394 MIPS_BRANCH ("b%F1", "%Z2%0"),
5395 MIPS_BRANCH ("b%W1", "%Z2%0"));
5396 }
5397 [(set_attr "type" "branch")])
5398
5399 (define_insn "*branch_fp_inverted"
5400 [(set (pc)
5401 (if_then_else
5402 (match_operator 1 "equality_operator"
5403 [(match_operand:CC 2 "register_operand" "z")
5404 (const_int 0)])
5405 (pc)
5406 (label_ref (match_operand 0 "" ""))))]
5407 "TARGET_HARD_FLOAT"
5408 {
5409 return mips_output_conditional_branch (insn, operands,
5410 MIPS_BRANCH ("b%W1", "%Z2%0"),
5411 MIPS_BRANCH ("b%F1", "%Z2%0"));
5412 }
5413 [(set_attr "type" "branch")])
5414
5415 ;; Conditional branches on ordered comparisons with zero.
5416
5417 (define_insn "*branch_order<mode>"
5418 [(set (pc)
5419 (if_then_else
5420 (match_operator 1 "order_operator"
5421 [(match_operand:GPR 2 "register_operand" "d")
5422 (const_int 0)])
5423 (label_ref (match_operand 0 "" ""))
5424 (pc)))]
5425 "!TARGET_MIPS16"
5426 { return mips_output_order_conditional_branch (insn, operands, false); }
5427 [(set_attr "type" "branch")])
5428
5429 (define_insn "*branch_order<mode>_inverted"
5430 [(set (pc)
5431 (if_then_else
5432 (match_operator 1 "order_operator"
5433 [(match_operand:GPR 2 "register_operand" "d")
5434 (const_int 0)])
5435 (pc)
5436 (label_ref (match_operand 0 "" ""))))]
5437 "!TARGET_MIPS16"
5438 { return mips_output_order_conditional_branch (insn, operands, true); }
5439 [(set_attr "type" "branch")])
5440
5441 ;; Conditional branch on equality comparison.
5442
5443 (define_insn "*branch_equality<mode>"
5444 [(set (pc)
5445 (if_then_else
5446 (match_operator 1 "equality_operator"
5447 [(match_operand:GPR 2 "register_operand" "d")
5448 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5449 (label_ref (match_operand 0 "" ""))
5450 (pc)))]
5451 "!TARGET_MIPS16"
5452 {
5453 return mips_output_conditional_branch (insn, operands,
5454 MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
5455 MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
5456 }
5457 [(set_attr "type" "branch")])
5458
5459 (define_insn "*branch_equality<mode>_inverted"
5460 [(set (pc)
5461 (if_then_else
5462 (match_operator 1 "equality_operator"
5463 [(match_operand:GPR 2 "register_operand" "d")
5464 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
5465 (pc)
5466 (label_ref (match_operand 0 "" ""))))]
5467 "!TARGET_MIPS16"
5468 {
5469 return mips_output_conditional_branch (insn, operands,
5470 MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
5471 MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
5472 }
5473 [(set_attr "type" "branch")])
5474
5475 ;; MIPS16 branches
5476
5477 (define_insn "*branch_equality<mode>_mips16"
5478 [(set (pc)
5479 (if_then_else
5480 (match_operator 1 "equality_operator"
5481 [(match_operand:GPR 2 "register_operand" "d,t")
5482 (const_int 0)])
5483 (label_ref (match_operand 0 "" ""))
5484 (pc)))]
5485 "TARGET_MIPS16"
5486 "@
5487 b%C1z\t%2,%0
5488 bt%C1z\t%0"
5489 [(set_attr "type" "branch")])
5490
5491 (define_insn "*branch_equality<mode>_mips16_inverted"
5492 [(set (pc)
5493 (if_then_else
5494 (match_operator 1 "equality_operator"
5495 [(match_operand:GPR 2 "register_operand" "d,t")
5496 (const_int 0)])
5497 (pc)
5498 (label_ref (match_operand 0 "" ""))))]
5499 "TARGET_MIPS16"
5500 "@
5501 b%N1z\t%2,%0
5502 bt%N1z\t%0"
5503 [(set_attr "type" "branch")])
5504
5505 (define_expand "cbranch<mode>4"
5506 [(set (pc)
5507 (if_then_else (match_operator 0 "comparison_operator"
5508 [(match_operand:GPR 1 "register_operand")
5509 (match_operand:GPR 2 "nonmemory_operand")])
5510 (label_ref (match_operand 3 ""))
5511 (pc)))]
5512 ""
5513 {
5514 mips_expand_conditional_branch (operands);
5515 DONE;
5516 })
5517
5518 (define_expand "cbranch<mode>4"
5519 [(set (pc)
5520 (if_then_else (match_operator 0 "comparison_operator"
5521 [(match_operand:SCALARF 1 "register_operand")
5522 (match_operand:SCALARF 2 "register_operand")])
5523 (label_ref (match_operand 3 ""))
5524 (pc)))]
5525 ""
5526 {
5527 mips_expand_conditional_branch (operands);
5528 DONE;
5529 })
5530
5531 ;; Used to implement built-in functions.
5532 (define_expand "condjump"
5533 [(set (pc)
5534 (if_then_else (match_operand 0)
5535 (label_ref (match_operand 1))
5536 (pc)))])
5537
5538 ;; Branch if bit is set/clear.
5539
5540 (define_insn "*branch_bit<bbv><mode>"
5541 [(set (pc)
5542 (if_then_else
5543 (equality_op (zero_extract:GPR
5544 (match_operand:GPR 1 "register_operand" "d")
5545 (const_int 1)
5546 (match_operand 2 "const_int_operand" ""))
5547 (const_int 0))
5548 (label_ref (match_operand 0 ""))
5549 (pc)))]
5550 "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5551 {
5552 return
5553 mips_output_conditional_branch (insn, operands,
5554 MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
5555 MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
5556 }
5557 [(set_attr "type" "branch")
5558 (set_attr "branch_likely" "no")])
5559
5560 (define_insn "*branch_bit<bbv><mode>_inverted"
5561 [(set (pc)
5562 (if_then_else
5563 (equality_op (zero_extract:GPR
5564 (match_operand:GPR 1 "register_operand" "d")
5565 (const_int 1)
5566 (match_operand 2 "const_int_operand" ""))
5567 (const_int 0))
5568 (pc)
5569 (label_ref (match_operand 0 ""))))]
5570 "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
5571 {
5572 return
5573 mips_output_conditional_branch (insn, operands,
5574 MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
5575 MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
5576 }
5577 [(set_attr "type" "branch")
5578 (set_attr "branch_likely" "no")])
5579 \f
5580 ;;
5581 ;; ....................
5582 ;;
5583 ;; SETTING A REGISTER FROM A COMPARISON
5584 ;;
5585 ;; ....................
5586
5587 ;; Destination is always set in SI mode.
5588
5589 (define_expand "cstore<mode>4"
5590 [(set (match_operand:SI 0 "register_operand")
5591 (match_operator:SI 1 "mips_cstore_operator"
5592 [(match_operand:GPR 2 "register_operand")
5593 (match_operand:GPR 3 "nonmemory_operand")]))]
5594 ""
5595 {
5596 mips_expand_scc (operands);
5597 DONE;
5598 })
5599
5600 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>"
5601 [(set (match_operand:GPR2 0 "register_operand" "=d")
5602 (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5603 (const_int 0)))]
5604 "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5605 "sltu\t%0,%1,1"
5606 [(set_attr "type" "slt")
5607 (set_attr "mode" "<GPR:MODE>")])
5608
5609 (define_insn "*seq_zero_<GPR:mode><GPR2:mode>_mips16"
5610 [(set (match_operand:GPR2 0 "register_operand" "=t")
5611 (eq:GPR2 (match_operand:GPR 1 "register_operand" "d")
5612 (const_int 0)))]
5613 "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5614 "sltu\t%1,1"
5615 [(set_attr "type" "slt")
5616 (set_attr "mode" "<GPR:MODE>")])
5617
5618 ;; Generate sltiu unless using seq results in better code.
5619 (define_insn "*seq_<GPR:mode><GPR2:mode>_seq"
5620 [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5621 (eq:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5622 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5623 "ISA_HAS_SEQ_SNE"
5624 "@
5625 seq\t%0,%1,%2
5626 sltiu\t%0,%1,1
5627 seqi\t%0,%1,%2"
5628 [(set_attr "type" "slt")
5629 (set_attr "mode" "<GPR:MODE>")])
5630
5631 (define_insn "*sne_zero_<GPR:mode><GPR2:mode>"
5632 [(set (match_operand:GPR2 0 "register_operand" "=d")
5633 (ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
5634 (const_int 0)))]
5635 "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE"
5636 "sltu\t%0,%.,%1"
5637 [(set_attr "type" "slt")
5638 (set_attr "mode" "<GPR:MODE>")])
5639
5640 ;; Generate sltu unless using sne results in better code.
5641 (define_insn "*sne_<GPR:mode><GPR2:mode>_sne"
5642 [(set (match_operand:GPR2 0 "register_operand" "=d,d,d")
5643 (ne:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d")
5644 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))]
5645 "ISA_HAS_SEQ_SNE"
5646 "@
5647 sne\t%0,%1,%2
5648 sltu\t%0,%.,%1
5649 snei\t%0,%1,%2"
5650 [(set_attr "type" "slt")
5651 (set_attr "mode" "<GPR:MODE>")])
5652
5653 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
5654 [(set (match_operand:GPR2 0 "register_operand" "=d")
5655 (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5656 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
5657 "!TARGET_MIPS16"
5658 "slt<u>\t%0,%z2,%1"
5659 [(set_attr "type" "slt")
5660 (set_attr "mode" "<GPR:MODE>")])
5661
5662 (define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16"
5663 [(set (match_operand:GPR2 0 "register_operand" "=t")
5664 (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5665 (match_operand:GPR 2 "register_operand" "d")))]
5666 "TARGET_MIPS16"
5667 "slt<u>\t%2,%1"
5668 [(set_attr "type" "slt")
5669 (set_attr "mode" "<GPR:MODE>")])
5670
5671 (define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
5672 [(set (match_operand:GPR2 0 "register_operand" "=d")
5673 (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
5674 (const_int 1)))]
5675 "!TARGET_MIPS16"
5676 "slt<u>\t%0,%.,%1"
5677 [(set_attr "type" "slt")
5678 (set_attr "mode" "<GPR:MODE>")])
5679
5680 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
5681 [(set (match_operand:GPR2 0 "register_operand" "=d")
5682 (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
5683 (match_operand:GPR 2 "arith_operand" "dI")))]
5684 "!TARGET_MIPS16"
5685 "slt<u>\t%0,%1,%2"
5686 [(set_attr "type" "slt")
5687 (set_attr "mode" "<GPR:MODE>")])
5688
5689 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
5690 [(set (match_operand:GPR2 0 "register_operand" "=t,t")
5691 (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
5692 (match_operand:GPR 2 "arith_operand" "d,I")))]
5693 "TARGET_MIPS16"
5694 "slt<u>\t%1,%2"
5695 [(set_attr "type" "slt")
5696 (set_attr "mode" "<GPR:MODE>")
5697 (set_attr_alternative "length"
5698 [(const_int 4)
5699 (if_then_else (match_operand 2 "m16_uimm8_1")
5700 (const_int 4)
5701 (const_int 8))])])
5702
5703 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
5704 [(set (match_operand:GPR2 0 "register_operand" "=d")
5705 (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5706 (match_operand:GPR 2 "sle_operand" "")))]
5707 "!TARGET_MIPS16"
5708 {
5709 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5710 return "slt<u>\t%0,%1,%2";
5711 }
5712 [(set_attr "type" "slt")
5713 (set_attr "mode" "<GPR:MODE>")])
5714
5715 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
5716 [(set (match_operand:GPR2 0 "register_operand" "=t")
5717 (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
5718 (match_operand:GPR 2 "sle_operand" "")))]
5719 "TARGET_MIPS16"
5720 {
5721 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5722 return "slt<u>\t%1,%2";
5723 }
5724 [(set_attr "type" "slt")
5725 (set_attr "mode" "<GPR:MODE>")
5726 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
5727 (const_int 4)
5728 (const_int 8)))])
5729 \f
5730 ;;
5731 ;; ....................
5732 ;;
5733 ;; FLOATING POINT COMPARISONS
5734 ;;
5735 ;; ....................
5736
5737 (define_insn "s<code>_<mode>"
5738 [(set (match_operand:CC 0 "register_operand" "=z")
5739 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5740 (match_operand:SCALARF 2 "register_operand" "f")))]
5741 ""
5742 "c.<fcond>.<fmt>\t%Z0%1,%2"
5743 [(set_attr "type" "fcmp")
5744 (set_attr "mode" "FPSW")])
5745
5746 (define_insn "s<code>_<mode>"
5747 [(set (match_operand:CC 0 "register_operand" "=z")
5748 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
5749 (match_operand:SCALARF 2 "register_operand" "f")))]
5750 ""
5751 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
5752 [(set_attr "type" "fcmp")
5753 (set_attr "mode" "FPSW")])
5754 \f
5755 ;;
5756 ;; ....................
5757 ;;
5758 ;; UNCONDITIONAL BRANCHES
5759 ;;
5760 ;; ....................
5761
5762 ;; Unconditional branches.
5763
5764 (define_expand "jump"
5765 [(set (pc)
5766 (label_ref (match_operand 0)))])
5767
5768 (define_insn "*jump_absolute"
5769 [(set (pc)
5770 (label_ref (match_operand 0)))]
5771 "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
5772 { return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); }
5773 [(set_attr "type" "jump")])
5774
5775 (define_insn "*jump_pic"
5776 [(set (pc)
5777 (label_ref (match_operand 0)))]
5778 "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
5779 {
5780 if (get_attr_length (insn) <= 8)
5781 return "%*b\t%l0%/";
5782 else
5783 {
5784 mips_output_load_label (operands[0]);
5785 return "%*jr\t%@%/%]";
5786 }
5787 }
5788 [(set_attr "type" "branch")])
5789
5790 ;; We need a different insn for the mips16, because a mips16 branch
5791 ;; does not have a delay slot.
5792
5793 (define_insn "*jump_mips16"
5794 [(set (pc)
5795 (label_ref (match_operand 0 "" "")))]
5796 "TARGET_MIPS16"
5797 "b\t%l0"
5798 [(set_attr "type" "branch")
5799 (set (attr "length")
5800 ;; This calculation is like the normal branch one, but the
5801 ;; range of the unextended instruction is [-0x800, 0x7fe] rather
5802 ;; than [-0x100, 0xfe]. This translates to a range of:
5803 ;;
5804 ;; [-(0x800 - sizeof (branch)), 0x7fe]
5805 ;; == [-0x7fe, 0x7fe]
5806 ;;
5807 ;; from the shorten_branches reference address. Long-branch
5808 ;; sequences will replace this one, so the minimum length
5809 ;; is one instruction shorter than for conditional branches.
5810 (cond [(and (le (minus (match_dup 0) (pc)) (const_int 2046))
5811 (le (minus (pc) (match_dup 0)) (const_int 2046)))
5812 (const_int 4)
5813 (and (le (minus (match_dup 0) (pc)) (const_int 65534))
5814 (le (minus (pc) (match_dup 0)) (const_int 65532)))
5815 (const_int 8)
5816 (and (match_test "TARGET_ABICALLS")
5817 (not (match_test "TARGET_ABSOLUTE_ABICALLS")))
5818 (const_int 36)
5819 (match_test "Pmode == SImode")
5820 (const_int 28)
5821 ] (const_int 44)))])
5822
5823 (define_expand "indirect_jump"
5824 [(set (pc) (match_operand 0 "register_operand"))]
5825 ""
5826 {
5827 operands[0] = force_reg (Pmode, operands[0]);
5828 emit_jump_insn (PMODE_INSN (gen_indirect_jump, (operands[0])));
5829 DONE;
5830 })
5831
5832 (define_insn "indirect_jump_<mode>"
5833 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5834 ""
5835 "%*j\t%0%/"
5836 [(set_attr "type" "jump")
5837 (set_attr "mode" "none")])
5838
5839 ;; A combined jump-and-move instruction, used for MIPS16 long-branch
5840 ;; sequences. Having a dedicated pattern is more convenient than
5841 ;; creating a SEQUENCE for this special case.
5842 (define_insn "indirect_jump_and_restore_<mode>"
5843 [(set (pc) (match_operand:P 1 "register_operand" "d"))
5844 (set (match_operand:P 0 "register_operand" "=d")
5845 (match_operand:P 2 "register_operand" "y"))]
5846 ""
5847 "%(%<jr\t%1\;move\t%0,%2%>%)"
5848 [(set_attr "type" "multi")
5849 (set_attr "extended_mips16" "yes")])
5850
5851 (define_expand "tablejump"
5852 [(set (pc)
5853 (match_operand 0 "register_operand"))
5854 (use (label_ref (match_operand 1 "")))]
5855 "!TARGET_MIPS16_SHORT_JUMP_TABLES"
5856 {
5857 if (TARGET_GPWORD)
5858 operands[0] = expand_binop (Pmode, add_optab, operands[0],
5859 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5860 else if (TARGET_RTP_PIC)
5861 {
5862 /* When generating RTP PIC, we use case table entries that are relative
5863 to the start of the function. Add the function's address to the
5864 value we loaded. */
5865 rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5866 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5867 start, 0, 0, OPTAB_WIDEN);
5868 }
5869
5870 emit_jump_insn (PMODE_INSN (gen_tablejump, (operands[0], operands[1])));
5871 DONE;
5872 })
5873
5874 (define_insn "tablejump_<mode>"
5875 [(set (pc)
5876 (match_operand:P 0 "register_operand" "d"))
5877 (use (label_ref (match_operand 1 "" "")))]
5878 ""
5879 "%*j\t%0%/"
5880 [(set_attr "type" "jump")
5881 (set_attr "mode" "none")])
5882
5883 ;; For MIPS16, we don't know whether a given jump table will use short or
5884 ;; word-sized offsets until late in compilation, when we are able to determine
5885 ;; the sizes of the insns which comprise the containing function. This
5886 ;; necessitates the use of the casesi rather than the tablejump pattern, since
5887 ;; the latter tries to calculate the index of the offset to jump through early
5888 ;; in compilation, i.e. at expand time, when nothing is known about the
5889 ;; eventual function layout.
5890
5891 (define_expand "casesi"
5892 [(match_operand:SI 0 "register_operand" "") ; index to jump on
5893 (match_operand:SI 1 "const_int_operand" "") ; lower bound
5894 (match_operand:SI 2 "const_int_operand" "") ; total range
5895 (match_operand 3 "" "") ; table label
5896 (match_operand 4 "" "")] ; out of range label
5897 "TARGET_MIPS16_SHORT_JUMP_TABLES"
5898 {
5899 if (operands[1] != const0_rtx)
5900 {
5901 rtx reg = gen_reg_rtx (SImode);
5902 rtx offset = gen_int_mode (-INTVAL (operands[1]), SImode);
5903
5904 if (!arith_operand (offset, SImode))
5905 offset = force_reg (SImode, offset);
5906
5907 emit_insn (gen_addsi3 (reg, operands[0], offset));
5908 operands[0] = reg;
5909 }
5910
5911 if (!arith_operand (operands[0], SImode))
5912 operands[0] = force_reg (SImode, operands[0]);
5913
5914 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5915
5916 emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16,
5917 (operands[0], operands[2],
5918 operands[3], operands[4])));
5919
5920 DONE;
5921 })
5922
5923 (define_insn "casesi_internal_mips16_<mode>"
5924 [(set (pc)
5925 (if_then_else
5926 (leu (match_operand:SI 0 "register_operand" "d")
5927 (match_operand:SI 1 "arith_operand" "dI"))
5928 (unspec:P
5929 [(match_dup 0)
5930 (label_ref (match_operand 2 "" ""))]
5931 UNSPEC_CASESI_DISPATCH)
5932 (label_ref (match_operand 3 "" ""))))
5933 (clobber (match_scratch:P 4 "=d"))
5934 (clobber (match_scratch:P 5 "=d"))
5935 (clobber (reg:SI MIPS16_T_REGNUM))]
5936 "TARGET_MIPS16_SHORT_JUMP_TABLES"
5937 {
5938 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
5939
5940 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
5941
5942 output_asm_insn ("sltu\t%0, %1", operands);
5943 output_asm_insn ("bteqz\t%3", operands);
5944
5945 switch (GET_MODE (diff_vec))
5946 {
5947 case HImode:
5948 output_asm_insn ("sll\t%5, %0, 1", operands);
5949 output_asm_insn ("la\t%4, %2", operands);
5950 output_asm_insn ("<d>addu\t%5, %4, %5", operands);
5951 output_asm_insn ("lh\t%5, 0(%5)", operands);
5952 break;
5953
5954 case SImode:
5955 output_asm_insn ("sll\t%5, %0, 2", operands);
5956 output_asm_insn ("la\t%4, %2", operands);
5957 output_asm_insn ("<d>addu\t%5, %4, %5", operands);
5958 output_asm_insn ("lw\t%5, 0(%5)", operands);
5959 break;
5960
5961 default:
5962 gcc_unreachable ();
5963 }
5964
5965 output_asm_insn ("addu\t%4, %4, %5", operands);
5966
5967 return "j\t%4";
5968 }
5969 [(set_attr "length" "32")])
5970
5971 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
5972 ;; While it is possible to either pull it off the stack (in the
5973 ;; o32 case) or recalculate it given t9 and our target label,
5974 ;; it takes 3 or 4 insns to do so.
5975
5976 (define_expand "builtin_setjmp_setup"
5977 [(use (match_operand 0 "register_operand"))]
5978 "TARGET_USE_GOT"
5979 {
5980 rtx addr;
5981
5982 addr = plus_constant (Pmode, operands[0], GET_MODE_SIZE (Pmode) * 3);
5983 mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5984 DONE;
5985 })
5986
5987 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
5988 ;; that older code did recalculate the gp from $25. Continue to jump through
5989 ;; $25 for compatibility (we lose nothing by doing so).
5990
5991 (define_expand "builtin_longjmp"
5992 [(use (match_operand 0 "register_operand"))]
5993 "TARGET_USE_GOT"
5994 {
5995 /* The elements of the buffer are, in order: */
5996 int W = GET_MODE_SIZE (Pmode);
5997 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5998 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 1*W));
5999 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 2*W));
6000 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 3*W));
6001 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6002 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6003 The target is bound to be using $28 as the global pointer
6004 but the current function might not be. */
6005 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6006
6007 /* This bit is similar to expand_builtin_longjmp except that it
6008 restores $gp as well. */
6009 mips_emit_move (hard_frame_pointer_rtx, fp);
6010 mips_emit_move (pv, lab);
6011 emit_stack_restore (SAVE_NONLOCAL, stack);
6012 mips_emit_move (gp, gpv);
6013 emit_use (hard_frame_pointer_rtx);
6014 emit_use (stack_pointer_rtx);
6015 emit_use (gp);
6016 emit_indirect_jump (pv);
6017 DONE;
6018 })
6019 \f
6020 ;;
6021 ;; ....................
6022 ;;
6023 ;; Function prologue/epilogue
6024 ;;
6025 ;; ....................
6026 ;;
6027
6028 (define_expand "prologue"
6029 [(const_int 1)]
6030 ""
6031 {
6032 mips_expand_prologue ();
6033 DONE;
6034 })
6035
6036 ;; Block any insns from being moved before this point, since the
6037 ;; profiling call to mcount can use various registers that aren't
6038 ;; saved or used to pass arguments.
6039
6040 (define_insn "blockage"
6041 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6042 ""
6043 ""
6044 [(set_attr "type" "ghost")
6045 (set_attr "mode" "none")])
6046
6047 (define_insn "probe_stack_range_<P:mode>"
6048 [(set (match_operand:P 0 "register_operand" "=d")
6049 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6050 (match_operand:P 2 "register_operand" "d")]
6051 UNSPEC_PROBE_STACK_RANGE))]
6052 ""
6053 { return mips_output_probe_stack_range (operands[0], operands[2]); }
6054 [(set_attr "type" "unknown")
6055 (set_attr "can_delay" "no")
6056 (set_attr "mode" "<MODE>")])
6057
6058 (define_expand "epilogue"
6059 [(const_int 2)]
6060 ""
6061 {
6062 mips_expand_epilogue (false);
6063 DONE;
6064 })
6065
6066 (define_expand "sibcall_epilogue"
6067 [(const_int 2)]
6068 ""
6069 {
6070 mips_expand_epilogue (true);
6071 DONE;
6072 })
6073
6074 ;; Trivial return. Make it look like a normal return insn as that
6075 ;; allows jump optimizations to work better.
6076
6077 (define_expand "return"
6078 [(simple_return)]
6079 "mips_can_use_return_insn ()"
6080 { mips_expand_before_return (); })
6081
6082 (define_expand "simple_return"
6083 [(simple_return)]
6084 ""
6085 { mips_expand_before_return (); })
6086
6087 (define_insn "*<optab>"
6088 [(any_return)]
6089 ""
6090 "%*j\t$31%/"
6091 [(set_attr "type" "jump")
6092 (set_attr "mode" "none")])
6093
6094 ;; Normal return.
6095
6096 (define_insn "<optab>_internal"
6097 [(any_return)
6098 (use (match_operand 0 "pmode_register_operand" ""))]
6099 ""
6100 "%*j\t%0%/"
6101 [(set_attr "type" "jump")
6102 (set_attr "mode" "none")])
6103
6104 ;; Exception return.
6105 (define_insn "mips_eret"
6106 [(return)
6107 (unspec_volatile [(const_int 0)] UNSPEC_ERET)]
6108 ""
6109 "eret"
6110 [(set_attr "type" "trap")
6111 (set_attr "mode" "none")])
6112
6113 ;; Debug exception return.
6114 (define_insn "mips_deret"
6115 [(return)
6116 (unspec_volatile [(const_int 0)] UNSPEC_DERET)]
6117 ""
6118 "deret"
6119 [(set_attr "type" "trap")
6120 (set_attr "mode" "none")])
6121
6122 ;; Disable interrupts.
6123 (define_insn "mips_di"
6124 [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
6125 ""
6126 "di"
6127 [(set_attr "type" "trap")
6128 (set_attr "mode" "none")])
6129
6130 ;; Execution hazard barrier.
6131 (define_insn "mips_ehb"
6132 [(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
6133 ""
6134 "ehb"
6135 [(set_attr "type" "trap")
6136 (set_attr "mode" "none")])
6137
6138 ;; Read GPR from previous shadow register set.
6139 (define_insn "mips_rdpgpr"
6140 [(set (match_operand:SI 0 "register_operand" "=d")
6141 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
6142 UNSPEC_RDPGPR))]
6143 ""
6144 "rdpgpr\t%0,%1"
6145 [(set_attr "type" "move")
6146 (set_attr "mode" "SI")])
6147
6148 ;; Move involving COP0 registers.
6149 (define_insn "cop0_move"
6150 [(set (match_operand:SI 0 "register_operand" "=B,d")
6151 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
6152 UNSPEC_COP0))]
6153 ""
6154 { return mips_output_move (operands[0], operands[1]); }
6155 [(set_attr "type" "mtc,mfc")
6156 (set_attr "mode" "SI")])
6157
6158 ;; This is used in compiling the unwind routines.
6159 (define_expand "eh_return"
6160 [(use (match_operand 0 "general_operand"))]
6161 ""
6162 {
6163 if (GET_MODE (operands[0]) != word_mode)
6164 operands[0] = convert_to_mode (word_mode, operands[0], 0);
6165 if (TARGET_64BIT)
6166 emit_insn (gen_eh_set_lr_di (operands[0]));
6167 else
6168 emit_insn (gen_eh_set_lr_si (operands[0]));
6169 DONE;
6170 })
6171
6172 ;; Clobber the return address on the stack. We can't expand this
6173 ;; until we know where it will be put in the stack frame.
6174
6175 (define_insn "eh_set_lr_si"
6176 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6177 (clobber (match_scratch:SI 1 "=&d"))]
6178 "! TARGET_64BIT"
6179 "#")
6180
6181 (define_insn "eh_set_lr_di"
6182 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6183 (clobber (match_scratch:DI 1 "=&d"))]
6184 "TARGET_64BIT"
6185 "#")
6186
6187 (define_split
6188 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6189 (clobber (match_scratch 1))]
6190 "reload_completed"
6191 [(const_int 0)]
6192 {
6193 mips_set_return_address (operands[0], operands[1]);
6194 DONE;
6195 })
6196
6197 (define_expand "exception_receiver"
6198 [(const_int 0)]
6199 "TARGET_USE_GOT"
6200 {
6201 /* See the comment above load_call<mode> for details. */
6202 emit_insn (gen_set_got_version ());
6203
6204 /* If we have a call-clobbered $gp, restore it from its save slot. */
6205 if (HAVE_restore_gp_si)
6206 emit_insn (gen_restore_gp_si ());
6207 else if (HAVE_restore_gp_di)
6208 emit_insn (gen_restore_gp_di ());
6209 DONE;
6210 })
6211
6212 (define_expand "nonlocal_goto_receiver"
6213 [(const_int 0)]
6214 "TARGET_USE_GOT"
6215 {
6216 /* See the comment above load_call<mode> for details. */
6217 emit_insn (gen_set_got_version ());
6218 DONE;
6219 })
6220
6221 ;; Restore $gp from its .cprestore stack slot. The instruction remains
6222 ;; volatile until all uses of $28 are exposed.
6223 (define_insn_and_split "restore_gp_<mode>"
6224 [(set (reg:P 28)
6225 (unspec_volatile:P [(const_int 0)] UNSPEC_RESTORE_GP))
6226 (clobber (match_scratch:P 0 "=&d"))]
6227 "TARGET_CALL_CLOBBERED_GP"
6228 "#"
6229 "&& epilogue_completed"
6230 [(const_int 0)]
6231 {
6232 mips_restore_gp_from_cprestore_slot (operands[0]);
6233 DONE;
6234 }
6235 [(set_attr "type" "ghost")])
6236
6237 ;; Move between $gp and its register save slot.
6238 (define_insn_and_split "move_gp<mode>"
6239 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m")
6240 (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")]
6241 UNSPEC_MOVE_GP))]
6242 ""
6243 { return mips_must_initialize_gp_p () ? "#" : ""; }
6244 "mips_must_initialize_gp_p ()"
6245 [(const_int 0)]
6246 {
6247 mips_emit_move (operands[0], operands[1]);
6248 DONE;
6249 }
6250 [(set_attr "type" "ghost")])
6251 \f
6252 ;;
6253 ;; ....................
6254 ;;
6255 ;; FUNCTION CALLS
6256 ;;
6257 ;; ....................
6258
6259 ;; Instructions to load a call address from the GOT. The address might
6260 ;; point to a function or to a lazy binding stub. In the latter case,
6261 ;; the stub will use the dynamic linker to resolve the function, which
6262 ;; in turn will change the GOT entry to point to the function's real
6263 ;; address.
6264 ;;
6265 ;; This means that every call, even pure and constant ones, can
6266 ;; potentially modify the GOT entry. And once a stub has been called,
6267 ;; we must not call it again.
6268 ;;
6269 ;; We represent this restriction using an imaginary, fixed, call-saved
6270 ;; register called GOT_VERSION_REGNUM. The idea is to make the register
6271 ;; live throughout the function and to change its value after every
6272 ;; potential call site. This stops any rtx value that uses the register
6273 ;; from being computed before an earlier call. To do this, we:
6274 ;;
6275 ;; - Ensure that the register is live on entry to the function,
6276 ;; so that it is never thought to be used uninitalized.
6277 ;;
6278 ;; - Ensure that the register is live on exit from the function,
6279 ;; so that it is live throughout.
6280 ;;
6281 ;; - Make each call (lazily-bound or not) use the current value
6282 ;; of GOT_VERSION_REGNUM, so that updates of the register are
6283 ;; not moved across call boundaries.
6284 ;;
6285 ;; - Add "ghost" definitions of the register to the beginning of
6286 ;; blocks reached by EH and ABNORMAL_CALL edges, because those
6287 ;; edges may involve calls that normal paths don't. (E.g. the
6288 ;; unwinding code that handles a non-call exception may change
6289 ;; lazily-bound GOT entries.) We do this by making the
6290 ;; exception_receiver and nonlocal_goto_receiver expanders emit
6291 ;; a set_got_version instruction.
6292 ;;
6293 ;; - After each call (lazily-bound or not), use a "ghost"
6294 ;; update_got_version instruction to change the register's value.
6295 ;; This instruction mimics the _possible_ effect of the dynamic
6296 ;; resolver during the call and it remains live even if the call
6297 ;; itself becomes dead.
6298 ;;
6299 ;; - Leave GOT_VERSION_REGNUM out of all register classes.
6300 ;; The register is therefore not a valid register_operand
6301 ;; and cannot be moved to or from other registers.
6302
6303 (define_insn "load_call<mode>"
6304 [(set (match_operand:P 0 "register_operand" "=d")
6305 (unspec:P [(match_operand:P 1 "register_operand" "d")
6306 (match_operand:P 2 "immediate_operand" "")
6307 (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
6308 "TARGET_USE_GOT"
6309 "<load>\t%0,%R2(%1)"
6310 [(set_attr "got" "load")
6311 (set_attr "mode" "<MODE>")])
6312
6313 (define_insn "set_got_version"
6314 [(set (reg:SI GOT_VERSION_REGNUM)
6315 (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))]
6316 "TARGET_USE_GOT"
6317 ""
6318 [(set_attr "type" "ghost")])
6319
6320 (define_insn "update_got_version"
6321 [(set (reg:SI GOT_VERSION_REGNUM)
6322 (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))]
6323 "TARGET_USE_GOT"
6324 ""
6325 [(set_attr "type" "ghost")])
6326
6327 ;; Sibling calls. All these patterns use jump instructions.
6328
6329 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
6330 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
6331 ;; is defined in terms of call_insn_operand, the same is true of the
6332 ;; constraints.
6333
6334 ;; When we use an indirect jump, we need a register that will be
6335 ;; preserved by the epilogue. Since TARGET_USE_PIC_FN_ADDR_REG forces
6336 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
6337 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
6338 ;; as well.
6339
6340 (define_expand "sibcall"
6341 [(parallel [(call (match_operand 0 "")
6342 (match_operand 1 ""))
6343 (use (match_operand 2 "")) ;; next_arg_reg
6344 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6345 "TARGET_SIBCALLS"
6346 {
6347 mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
6348 operands[1], operands[2], false);
6349 DONE;
6350 })
6351
6352 (define_insn "sibcall_internal"
6353 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
6354 (match_operand 1 "" ""))]
6355 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6356 { return MIPS_CALL ("j", operands, 0, 1); }
6357 [(set_attr "jal" "indirect,direct")
6358 (set_attr "jal_macro" "no")])
6359
6360 (define_expand "sibcall_value"
6361 [(parallel [(set (match_operand 0 "")
6362 (call (match_operand 1 "")
6363 (match_operand 2 "")))
6364 (use (match_operand 3 ""))])] ;; next_arg_reg
6365 "TARGET_SIBCALLS"
6366 {
6367 mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
6368 operands[2], operands[3], false);
6369 DONE;
6370 })
6371
6372 (define_insn "sibcall_value_internal"
6373 [(set (match_operand 0 "register_operand" "")
6374 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6375 (match_operand 2 "" "")))]
6376 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6377 { return MIPS_CALL ("j", operands, 1, 2); }
6378 [(set_attr "jal" "indirect,direct")
6379 (set_attr "jal_macro" "no")])
6380
6381 (define_insn "sibcall_value_multiple_internal"
6382 [(set (match_operand 0 "register_operand" "")
6383 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
6384 (match_operand 2 "" "")))
6385 (set (match_operand 3 "register_operand" "")
6386 (call (mem:SI (match_dup 1))
6387 (match_dup 2)))]
6388 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
6389 { return MIPS_CALL ("j", operands, 1, 2); }
6390 [(set_attr "jal" "indirect,direct")
6391 (set_attr "jal_macro" "no")])
6392
6393 (define_expand "call"
6394 [(parallel [(call (match_operand 0 "")
6395 (match_operand 1 ""))
6396 (use (match_operand 2 "")) ;; next_arg_reg
6397 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
6398 ""
6399 {
6400 mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
6401 operands[1], operands[2], false);
6402 DONE;
6403 })
6404
6405 ;; This instruction directly corresponds to an assembly-language "jal".
6406 ;; There are four cases:
6407 ;;
6408 ;; - -mno-abicalls:
6409 ;; Both symbolic and register destinations are OK. The pattern
6410 ;; always expands to a single mips instruction.
6411 ;;
6412 ;; - -mabicalls/-mno-explicit-relocs:
6413 ;; Again, both symbolic and register destinations are OK.
6414 ;; The call is treated as a multi-instruction black box.
6415 ;;
6416 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
6417 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
6418 ;; instruction.
6419 ;;
6420 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
6421 ;; Only "jal $25" is allowed. The call is actually two instructions:
6422 ;; "jalr $25" followed by an insn to reload $gp.
6423 ;;
6424 ;; In the last case, we can generate the individual instructions with
6425 ;; a define_split. There are several things to be wary of:
6426 ;;
6427 ;; - We can't expose the load of $gp before reload. If we did,
6428 ;; it might get removed as dead, but reload can introduce new
6429 ;; uses of $gp by rematerializing constants.
6430 ;;
6431 ;; - We shouldn't restore $gp after calls that never return.
6432 ;; It isn't valid to insert instructions between a noreturn
6433 ;; call and the following barrier.
6434 ;;
6435 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
6436 ;; instruction preserves $gp and so have no effect on its liveness.
6437 ;; But once we generate the separate insns, it becomes obvious that
6438 ;; $gp is not live on entry to the call.
6439 ;;
6440 (define_insn_and_split "call_internal"
6441 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6442 (match_operand 1 "" ""))
6443 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6444 ""
6445 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); }
6446 "reload_completed && TARGET_SPLIT_CALLS"
6447 [(const_int 0)]
6448 {
6449 mips_split_call (curr_insn, gen_call_split (operands[0], operands[1]));
6450 DONE;
6451 }
6452 [(set_attr "jal" "indirect,direct")])
6453
6454 (define_insn "call_split"
6455 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
6456 (match_operand 1 "" ""))
6457 (clobber (reg:SI RETURN_ADDR_REGNUM))
6458 (clobber (reg:SI 28))]
6459 "TARGET_SPLIT_CALLS"
6460 { return MIPS_CALL ("jal", operands, 0, 1); }
6461 [(set_attr "jal" "indirect,direct")
6462 (set_attr "jal_macro" "no")])
6463
6464 ;; A pattern for calls that must be made directly. It is used for
6465 ;; MIPS16 calls that the linker may need to redirect to a hard-float
6466 ;; stub; the linker relies on the call relocation type to detect when
6467 ;; such redirection is needed.
6468 (define_insn_and_split "call_internal_direct"
6469 [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6470 (match_operand 1))
6471 (const_int 1)
6472 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6473 ""
6474 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); }
6475 "reload_completed && TARGET_SPLIT_CALLS"
6476 [(const_int 0)]
6477 {
6478 mips_split_call (curr_insn,
6479 gen_call_direct_split (operands[0], operands[1]));
6480 DONE;
6481 }
6482 [(set_attr "jal" "direct")])
6483
6484 (define_insn "call_direct_split"
6485 [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
6486 (match_operand 1))
6487 (const_int 1)
6488 (clobber (reg:SI RETURN_ADDR_REGNUM))
6489 (clobber (reg:SI 28))]
6490 "TARGET_SPLIT_CALLS"
6491 { return MIPS_CALL ("jal", operands, 0, -1); }
6492 [(set_attr "jal" "direct")
6493 (set_attr "jal_macro" "no")])
6494
6495 (define_expand "call_value"
6496 [(parallel [(set (match_operand 0 "")
6497 (call (match_operand 1 "")
6498 (match_operand 2 "")))
6499 (use (match_operand 3 ""))])] ;; next_arg_reg
6500 ""
6501 {
6502 mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
6503 operands[2], operands[3], false);
6504 DONE;
6505 })
6506
6507 ;; See comment for call_internal.
6508 (define_insn_and_split "call_value_internal"
6509 [(set (match_operand 0 "register_operand" "")
6510 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6511 (match_operand 2 "" "")))
6512 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6513 ""
6514 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6515 "reload_completed && TARGET_SPLIT_CALLS"
6516 [(const_int 0)]
6517 {
6518 mips_split_call (curr_insn,
6519 gen_call_value_split (operands[0], operands[1],
6520 operands[2]));
6521 DONE;
6522 }
6523 [(set_attr "jal" "indirect,direct")])
6524
6525 (define_insn "call_value_split"
6526 [(set (match_operand 0 "register_operand" "")
6527 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6528 (match_operand 2 "" "")))
6529 (clobber (reg:SI RETURN_ADDR_REGNUM))
6530 (clobber (reg:SI 28))]
6531 "TARGET_SPLIT_CALLS"
6532 { return MIPS_CALL ("jal", operands, 1, 2); }
6533 [(set_attr "jal" "indirect,direct")
6534 (set_attr "jal_macro" "no")])
6535
6536 ;; See call_internal_direct.
6537 (define_insn_and_split "call_value_internal_direct"
6538 [(set (match_operand 0 "register_operand")
6539 (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6540 (match_operand 2)))
6541 (const_int 1)
6542 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6543 ""
6544 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); }
6545 "reload_completed && TARGET_SPLIT_CALLS"
6546 [(const_int 0)]
6547 {
6548 mips_split_call (curr_insn,
6549 gen_call_value_direct_split (operands[0], operands[1],
6550 operands[2]));
6551 DONE;
6552 }
6553 [(set_attr "jal" "direct")])
6554
6555 (define_insn "call_value_direct_split"
6556 [(set (match_operand 0 "register_operand")
6557 (call (mem:SI (match_operand 1 "const_call_insn_operand"))
6558 (match_operand 2)))
6559 (const_int 1)
6560 (clobber (reg:SI RETURN_ADDR_REGNUM))
6561 (clobber (reg:SI 28))]
6562 "TARGET_SPLIT_CALLS"
6563 { return MIPS_CALL ("jal", operands, 1, -1); }
6564 [(set_attr "jal" "direct")
6565 (set_attr "jal_macro" "no")])
6566
6567 ;; See comment for call_internal.
6568 (define_insn_and_split "call_value_multiple_internal"
6569 [(set (match_operand 0 "register_operand" "")
6570 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6571 (match_operand 2 "" "")))
6572 (set (match_operand 3 "register_operand" "")
6573 (call (mem:SI (match_dup 1))
6574 (match_dup 2)))
6575 (clobber (reg:SI RETURN_ADDR_REGNUM))]
6576 ""
6577 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); }
6578 "reload_completed && TARGET_SPLIT_CALLS"
6579 [(const_int 0)]
6580 {
6581 mips_split_call (curr_insn,
6582 gen_call_value_multiple_split (operands[0], operands[1],
6583 operands[2], operands[3]));
6584 DONE;
6585 }
6586 [(set_attr "jal" "indirect,direct")])
6587
6588 (define_insn "call_value_multiple_split"
6589 [(set (match_operand 0 "register_operand" "")
6590 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
6591 (match_operand 2 "" "")))
6592 (set (match_operand 3 "register_operand" "")
6593 (call (mem:SI (match_dup 1))
6594 (match_dup 2)))
6595 (clobber (reg:SI RETURN_ADDR_REGNUM))
6596 (clobber (reg:SI 28))]
6597 "TARGET_SPLIT_CALLS"
6598 { return MIPS_CALL ("jal", operands, 1, 2); }
6599 [(set_attr "jal" "indirect,direct")
6600 (set_attr "jal_macro" "no")])
6601
6602 ;; Call subroutine returning any type.
6603
6604 (define_expand "untyped_call"
6605 [(parallel [(call (match_operand 0 "")
6606 (const_int 0))
6607 (match_operand 1 "")
6608 (match_operand 2 "")])]
6609 ""
6610 {
6611 int i;
6612
6613 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6614
6615 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6616 {
6617 rtx set = XVECEXP (operands[2], 0, i);
6618 mips_emit_move (SET_DEST (set), SET_SRC (set));
6619 }
6620
6621 emit_insn (gen_blockage ());
6622 DONE;
6623 })
6624 \f
6625 ;;
6626 ;; ....................
6627 ;;
6628 ;; MISC.
6629 ;;
6630 ;; ....................
6631 ;;
6632
6633
6634 (define_insn "prefetch"
6635 [(prefetch (match_operand:QI 0 "address_operand" "p")
6636 (match_operand 1 "const_int_operand" "n")
6637 (match_operand 2 "const_int_operand" "n"))]
6638 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
6639 {
6640 if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
6641 /* Loongson 2[ef] and Loongson 3a use load to $0 to perform prefetching. */
6642 return "ld\t$0,%a0";
6643 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
6644 return "pref\t%1,%a0";
6645 }
6646 [(set_attr "type" "prefetch")])
6647
6648 (define_insn "*prefetch_indexed_<mode>"
6649 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
6650 (match_operand:P 1 "register_operand" "d"))
6651 (match_operand 2 "const_int_operand" "n")
6652 (match_operand 3 "const_int_operand" "n"))]
6653 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6654 {
6655 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
6656 return "prefx\t%2,%1(%0)";
6657 }
6658 [(set_attr "type" "prefetchx")])
6659
6660 (define_insn "nop"
6661 [(const_int 0)]
6662 ""
6663 "%(nop%)"
6664 [(set_attr "type" "nop")
6665 (set_attr "mode" "none")])
6666
6667 ;; Like nop, but commented out when outside a .set noreorder block.
6668 (define_insn "hazard_nop"
6669 [(const_int 1)]
6670 ""
6671 {
6672 if (mips_noreorder.nesting_level > 0)
6673 return "nop";
6674 else
6675 return "#nop";
6676 }
6677 [(set_attr "type" "nop")])
6678 \f
6679 ;; MIPS4 Conditional move instructions.
6680
6681 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
6682 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6683 (if_then_else:GPR
6684 (match_operator:MOVECC 4 "equality_operator"
6685 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6686 (const_int 0)])
6687 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
6688 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
6689 "ISA_HAS_CONDMOVE"
6690 "@
6691 mov%T4\t%0,%z2,%1
6692 mov%t4\t%0,%z3,%1"
6693 [(set_attr "type" "condmove")
6694 (set_attr "mode" "<GPR:MODE>")])
6695
6696 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
6697 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
6698 (if_then_else:SCALARF
6699 (match_operator:MOVECC 4 "equality_operator"
6700 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
6701 (const_int 0)])
6702 (match_operand:SCALARF 2 "register_operand" "f,0")
6703 (match_operand:SCALARF 3 "register_operand" "0,f")))]
6704 "ISA_HAS_FP_CONDMOVE"
6705 "@
6706 mov%T4.<fmt>\t%0,%2,%1
6707 mov%t4.<fmt>\t%0,%3,%1"
6708 [(set_attr "type" "condmove")
6709 (set_attr "mode" "<SCALARF:MODE>")])
6710
6711 ;; These are the main define_expand's used to make conditional moves.
6712
6713 (define_expand "mov<mode>cc"
6714 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6715 (set (match_operand:GPR 0 "register_operand")
6716 (if_then_else:GPR (match_dup 5)
6717 (match_operand:GPR 2 "reg_or_0_operand")
6718 (match_operand:GPR 3 "reg_or_0_operand")))]
6719 "ISA_HAS_CONDMOVE"
6720 {
6721 mips_expand_conditional_move (operands);
6722 DONE;
6723 })
6724
6725 (define_expand "mov<mode>cc"
6726 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
6727 (set (match_operand:SCALARF 0 "register_operand")
6728 (if_then_else:SCALARF (match_dup 5)
6729 (match_operand:SCALARF 2 "register_operand")
6730 (match_operand:SCALARF 3 "register_operand")))]
6731 "ISA_HAS_FP_CONDMOVE"
6732 {
6733 mips_expand_conditional_move (operands);
6734 DONE;
6735 })
6736 \f
6737 ;;
6738 ;; ....................
6739 ;;
6740 ;; mips16 inline constant tables
6741 ;;
6742 ;; ....................
6743 ;;
6744
6745 (define_insn "consttable_tls_reloc"
6746 [(unspec_volatile [(match_operand 0 "tls_reloc_operand" "")
6747 (match_operand 1 "const_int_operand" "")]
6748 UNSPEC_CONSTTABLE_INT)]
6749 "TARGET_MIPS16_PCREL_LOADS"
6750 { return mips_output_tls_reloc_directive (&operands[0]); }
6751 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6752
6753 (define_insn "consttable_int"
6754 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
6755 (match_operand 1 "const_int_operand" "")]
6756 UNSPEC_CONSTTABLE_INT)]
6757 "TARGET_MIPS16"
6758 {
6759 assemble_integer (mips_strip_unspec_address (operands[0]),
6760 INTVAL (operands[1]),
6761 BITS_PER_UNIT * INTVAL (operands[1]), 1);
6762 return "";
6763 }
6764 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
6765
6766 (define_insn "consttable_float"
6767 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
6768 UNSPEC_CONSTTABLE_FLOAT)]
6769 "TARGET_MIPS16"
6770 {
6771 REAL_VALUE_TYPE d;
6772
6773 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
6774 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
6775 assemble_real (d, GET_MODE (operands[0]),
6776 GET_MODE_BITSIZE (GET_MODE (operands[0])));
6777 return "";
6778 }
6779 [(set (attr "length")
6780 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
6781
6782 (define_insn "align"
6783 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
6784 ""
6785 ".align\t%0"
6786 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
6787 \f
6788 (define_split
6789 [(match_operand 0 "small_data_pattern")]
6790 "reload_completed"
6791 [(match_dup 0)]
6792 { operands[0] = mips_rewrite_small_data (operands[0]); })
6793
6794 ;;
6795 ;; ....................
6796 ;;
6797 ;; MIPS16e Save/Restore
6798 ;;
6799 ;; ....................
6800 ;;
6801
6802 (define_insn "*mips16e_save_restore"
6803 [(match_parallel 0 ""
6804 [(set (match_operand:SI 1 "register_operand")
6805 (plus:SI (match_dup 1)
6806 (match_operand:SI 2 "const_int_operand")))])]
6807 "operands[1] == stack_pointer_rtx
6808 && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
6809 { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
6810 [(set_attr "type" "arith")
6811 (set_attr "extended_mips16" "yes")])
6812
6813 ;; Thread-Local Storage
6814
6815 ;; The TLS base pointer is accessed via "rdhwr $3, $29". No current
6816 ;; MIPS architecture defines this register, and no current
6817 ;; implementation provides it; instead, any OS which supports TLS is
6818 ;; expected to trap and emulate this instruction. rdhwr is part of the
6819 ;; MIPS 32r2 specification, but we use it on any architecture because
6820 ;; we expect it to be emulated. Use .set to force the assembler to
6821 ;; accept it.
6822 ;;
6823 ;; We do not use a constraint to force the destination to be $3
6824 ;; because $3 can appear explicitly as a function return value.
6825 ;; If we leave the use of $3 implicit in the constraints until
6826 ;; reload, we may end up making a $3 return value live across
6827 ;; the instruction, leading to a spill failure when reloading it.
6828 (define_insn_and_split "tls_get_tp_<mode>"
6829 [(set (match_operand:P 0 "register_operand" "=d")
6830 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
6831 (clobber (reg:P TLS_GET_TP_REGNUM))]
6832 "HAVE_AS_TLS && !TARGET_MIPS16"
6833 "#"
6834 "&& reload_completed"
6835 [(set (reg:P TLS_GET_TP_REGNUM)
6836 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
6837 (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
6838 ""
6839 [(set_attr "type" "unknown")
6840 ; Since rdhwr always generates a trap for now, putting it in a delay
6841 ; slot would make the kernel's emulation of it much slower.
6842 (set_attr "can_delay" "no")
6843 (set_attr "mode" "<MODE>")
6844 (set_attr "length" "8")])
6845
6846 (define_insn "*tls_get_tp_<mode>_split"
6847 [(set (reg:P TLS_GET_TP_REGNUM)
6848 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
6849 "HAVE_AS_TLS && !TARGET_MIPS16"
6850 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
6851 [(set_attr "type" "unknown")
6852 ; See tls_get_tp_<mode>
6853 (set_attr "can_delay" "no")
6854 (set_attr "mode" "<MODE>")])
6855
6856 ;; In MIPS16 mode, the TLS base pointer is accessed by a
6857 ;; libgcc helper function __mips16_rdhwr(), as 'rdhwr' is not
6858 ;; accessible in MIPS16.
6859 ;;
6860 ;; This is not represented as a call insn, to avoid the
6861 ;; unnecesarry clobbering of caller-save registers by a
6862 ;; function consisting only of: "rdhwr $3,$29; j $31; nop;"
6863 ;;
6864 ;; A $25 clobber is added to cater for a $25 load stub added by the
6865 ;; linker to __mips16_rdhwr when the call is made from non-PIC code.
6866
6867 (define_insn_and_split "tls_get_tp_mips16_<mode>"
6868 [(set (match_operand:P 0 "register_operand" "=d")
6869 (unspec:P [(match_operand:P 1 "call_insn_operand" "dS")]
6870 UNSPEC_TLS_GET_TP))
6871 (clobber (reg:P TLS_GET_TP_REGNUM))
6872 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
6873 (clobber (reg:P RETURN_ADDR_REGNUM))]
6874 "HAVE_AS_TLS && TARGET_MIPS16"
6875 "#"
6876 "&& reload_completed"
6877 [(parallel [(set (reg:P TLS_GET_TP_REGNUM)
6878 (unspec:P [(match_dup 1)] UNSPEC_TLS_GET_TP))
6879 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
6880 (clobber (reg:P RETURN_ADDR_REGNUM))])
6881 (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
6882 ""
6883 [(set_attr "type" "multi")
6884 (set_attr "length" "16")
6885 (set_attr "mode" "<MODE>")])
6886
6887 (define_insn "*tls_get_tp_mips16_call_<mode>"
6888 [(set (reg:P TLS_GET_TP_REGNUM)
6889 (unspec:P [(match_operand:P 0 "call_insn_operand" "dS")]
6890 UNSPEC_TLS_GET_TP))
6891 (clobber (reg:P PIC_FUNCTION_ADDR_REGNUM))
6892 (clobber (reg:P RETURN_ADDR_REGNUM))]
6893 "HAVE_AS_TLS && TARGET_MIPS16"
6894 { return MIPS_CALL ("jal", operands, 0, -1); }
6895 [(set_attr "type" "call")
6896 (set_attr "length" "12")
6897 (set_attr "mode" "<MODE>")])
6898
6899 ;; Named pattern for expanding thread pointer reference.
6900 (define_expand "get_thread_pointer<mode>"
6901 [(match_operand:P 0 "register_operand" "=d")]
6902 "HAVE_AS_TLS"
6903 {
6904 mips_expand_thread_pointer (operands[0]);
6905 DONE;
6906 })
6907
6908 \f
6909 ;; Synchronization instructions.
6910
6911 (include "sync.md")
6912
6913 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
6914
6915 (include "mips-ps-3d.md")
6916
6917 ; The MIPS DSP Instructions.
6918
6919 (include "mips-dsp.md")
6920
6921 ; The MIPS DSP REV 2 Instructions.
6922
6923 (include "mips-dspr2.md")
6924
6925 ; MIPS fixed-point instructions.
6926 (include "mips-fixed.md")
6927
6928 ; ST-Microelectronics Loongson-2E/2F-specific patterns.
6929 (include "loongson.md")
6930
6931 (define_c_enum "unspec" [
6932 UNSPEC_ADDRESS_FIRST
6933 ])