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