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