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