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