mips.md (*extendqihi2): Convert the destination to SImode.
[gcc.git] / gcc / config / mips / mips.md
1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
6 ;; Changes by Michael Meissner, meissner@osf.org
7 ;; 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
8 ;; Brendan Eich, brendan@microunity.com.
9
10 ;; This file is part of GCC.
11
12 ;; GCC is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; GCC is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GCC; see the file COPYING. If not, write to
24 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26
27 (define_constants
28 [(UNSPEC_LOAD_DF_LOW 0)
29 (UNSPEC_LOAD_DF_HIGH 1)
30 (UNSPEC_STORE_DF_HIGH 2)
31 (UNSPEC_GET_FNADDR 3)
32 (UNSPEC_BLOCKAGE 4)
33 (UNSPEC_CPRESTORE 5)
34 (UNSPEC_NONLOCAL_GOTO_RECEIVER 6)
35 (UNSPEC_EH_RETURN 7)
36 (UNSPEC_CONSTTABLE_INT 8)
37 (UNSPEC_CONSTTABLE_FLOAT 9)
38 (UNSPEC_ALIGN 14)
39 (UNSPEC_HIGH 17)
40 (UNSPEC_LOAD_LEFT 18)
41 (UNSPEC_LOAD_RIGHT 19)
42 (UNSPEC_STORE_LEFT 20)
43 (UNSPEC_STORE_RIGHT 21)
44 (UNSPEC_LOADGP 22)
45 (UNSPEC_LOAD_CALL 23)
46 (UNSPEC_LOAD_GOT 24)
47 (UNSPEC_GP 25)
48 (UNSPEC_MFHILO 26)
49 (UNSPEC_TLS_LDM 27)
50 (UNSPEC_TLS_GET_TP 28)
51 (UNSPEC_MFHC1 31)
52 (UNSPEC_MTHC1 32)
53 (UNSPEC_CLEAR_HAZARD 33)
54 (UNSPEC_RDHWR 34)
55 (UNSPEC_SYNCI 35)
56 (UNSPEC_SYNC 36)
57
58 (UNSPEC_ADDRESS_FIRST 100)
59
60 (FAKE_CALL_REGNO 79)
61
62 ;; For MIPS Paired-Singled Floating Point Instructions.
63
64 (UNSPEC_MOVE_TF_PS 200)
65 (UNSPEC_C 201)
66
67 ;; MIPS64/MIPS32R2 alnv.ps
68 (UNSPEC_ALNV_PS 202)
69
70 ;; MIPS-3D instructions
71 (UNSPEC_CABS 203)
72
73 (UNSPEC_ADDR_PS 204)
74 (UNSPEC_CVT_PW_PS 205)
75 (UNSPEC_CVT_PS_PW 206)
76 (UNSPEC_MULR_PS 207)
77 (UNSPEC_ABS_PS 208)
78
79 (UNSPEC_RSQRT1 209)
80 (UNSPEC_RSQRT2 210)
81 (UNSPEC_RECIP1 211)
82 (UNSPEC_RECIP2 212)
83 (UNSPEC_SINGLE_CC 213)
84 (UNSPEC_SCC 214)
85
86 ;; MIPS DSP ASE Revision 0.98 3/24/2005
87 (UNSPEC_ADDQ 300)
88 (UNSPEC_ADDQ_S 301)
89 (UNSPEC_SUBQ 302)
90 (UNSPEC_SUBQ_S 303)
91 (UNSPEC_ADDSC 304)
92 (UNSPEC_ADDWC 305)
93 (UNSPEC_MODSUB 306)
94 (UNSPEC_RADDU_W_QB 307)
95 (UNSPEC_ABSQ_S 308)
96 (UNSPEC_PRECRQ_QB_PH 309)
97 (UNSPEC_PRECRQ_PH_W 310)
98 (UNSPEC_PRECRQ_RS_PH_W 311)
99 (UNSPEC_PRECRQU_S_QB_PH 312)
100 (UNSPEC_PRECEQ_W_PHL 313)
101 (UNSPEC_PRECEQ_W_PHR 314)
102 (UNSPEC_PRECEQU_PH_QBL 315)
103 (UNSPEC_PRECEQU_PH_QBR 316)
104 (UNSPEC_PRECEQU_PH_QBLA 317)
105 (UNSPEC_PRECEQU_PH_QBRA 318)
106 (UNSPEC_PRECEU_PH_QBL 319)
107 (UNSPEC_PRECEU_PH_QBR 320)
108 (UNSPEC_PRECEU_PH_QBLA 321)
109 (UNSPEC_PRECEU_PH_QBRA 322)
110 (UNSPEC_SHLL 323)
111 (UNSPEC_SHLL_S 324)
112 (UNSPEC_SHRL_QB 325)
113 (UNSPEC_SHRA_PH 326)
114 (UNSPEC_SHRA_R 327)
115 (UNSPEC_MULEU_S_PH_QBL 328)
116 (UNSPEC_MULEU_S_PH_QBR 329)
117 (UNSPEC_MULQ_RS_PH 330)
118 (UNSPEC_MULEQ_S_W_PHL 331)
119 (UNSPEC_MULEQ_S_W_PHR 332)
120 (UNSPEC_DPAU_H_QBL 333)
121 (UNSPEC_DPAU_H_QBR 334)
122 (UNSPEC_DPSU_H_QBL 335)
123 (UNSPEC_DPSU_H_QBR 336)
124 (UNSPEC_DPAQ_S_W_PH 337)
125 (UNSPEC_DPSQ_S_W_PH 338)
126 (UNSPEC_MULSAQ_S_W_PH 339)
127 (UNSPEC_DPAQ_SA_L_W 340)
128 (UNSPEC_DPSQ_SA_L_W 341)
129 (UNSPEC_MAQ_S_W_PHL 342)
130 (UNSPEC_MAQ_S_W_PHR 343)
131 (UNSPEC_MAQ_SA_W_PHL 344)
132 (UNSPEC_MAQ_SA_W_PHR 345)
133 (UNSPEC_BITREV 346)
134 (UNSPEC_INSV 347)
135 (UNSPEC_REPL_QB 348)
136 (UNSPEC_REPL_PH 349)
137 (UNSPEC_CMP_EQ 350)
138 (UNSPEC_CMP_LT 351)
139 (UNSPEC_CMP_LE 352)
140 (UNSPEC_CMPGU_EQ_QB 353)
141 (UNSPEC_CMPGU_LT_QB 354)
142 (UNSPEC_CMPGU_LE_QB 355)
143 (UNSPEC_PICK 356)
144 (UNSPEC_PACKRL_PH 357)
145 (UNSPEC_EXTR_W 358)
146 (UNSPEC_EXTR_R_W 359)
147 (UNSPEC_EXTR_RS_W 360)
148 (UNSPEC_EXTR_S_H 361)
149 (UNSPEC_EXTP 362)
150 (UNSPEC_EXTPDP 363)
151 (UNSPEC_SHILO 364)
152 (UNSPEC_MTHLIP 365)
153 (UNSPEC_WRDSP 366)
154 (UNSPEC_RDDSP 367)
155
156 ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006
157 (UNSPEC_ABSQ_S_QB 400)
158 (UNSPEC_ADDU_PH 401)
159 (UNSPEC_ADDU_S_PH 402)
160 (UNSPEC_ADDUH_QB 403)
161 (UNSPEC_ADDUH_R_QB 404)
162 (UNSPEC_APPEND 405)
163 (UNSPEC_BALIGN 406)
164 (UNSPEC_CMPGDU_EQ_QB 407)
165 (UNSPEC_CMPGDU_LT_QB 408)
166 (UNSPEC_CMPGDU_LE_QB 409)
167 (UNSPEC_DPA_W_PH 410)
168 (UNSPEC_DPS_W_PH 411)
169 (UNSPEC_MADD 412)
170 (UNSPEC_MADDU 413)
171 (UNSPEC_MSUB 414)
172 (UNSPEC_MSUBU 415)
173 (UNSPEC_MUL_PH 416)
174 (UNSPEC_MUL_S_PH 417)
175 (UNSPEC_MULQ_RS_W 418)
176 (UNSPEC_MULQ_S_PH 419)
177 (UNSPEC_MULQ_S_W 420)
178 (UNSPEC_MULSA_W_PH 421)
179 (UNSPEC_MULT 422)
180 (UNSPEC_MULTU 423)
181 (UNSPEC_PRECR_QB_PH 424)
182 (UNSPEC_PRECR_SRA_PH_W 425)
183 (UNSPEC_PRECR_SRA_R_PH_W 426)
184 (UNSPEC_PREPEND 427)
185 (UNSPEC_SHRA_QB 428)
186 (UNSPEC_SHRA_R_QB 429)
187 (UNSPEC_SHRL_PH 430)
188 (UNSPEC_SUBU_PH 431)
189 (UNSPEC_SUBU_S_PH 432)
190 (UNSPEC_SUBUH_QB 433)
191 (UNSPEC_SUBUH_R_QB 434)
192 (UNSPEC_ADDQH_PH 435)
193 (UNSPEC_ADDQH_R_PH 436)
194 (UNSPEC_ADDQH_W 437)
195 (UNSPEC_ADDQH_R_W 438)
196 (UNSPEC_SUBQH_PH 439)
197 (UNSPEC_SUBQH_R_PH 440)
198 (UNSPEC_SUBQH_W 441)
199 (UNSPEC_SUBQH_R_W 442)
200 (UNSPEC_DPAX_W_PH 443)
201 (UNSPEC_DPSX_W_PH 444)
202 (UNSPEC_DPAQX_S_W_PH 445)
203 (UNSPEC_DPAQX_SA_W_PH 446)
204 (UNSPEC_DPSQX_S_W_PH 447)
205 (UNSPEC_DPSQX_SA_W_PH 448)
206 ]
207 )
208
209 (include "predicates.md")
210 (include "constraints.md")
211 \f
212 ;; ....................
213 ;;
214 ;; Attributes
215 ;;
216 ;; ....................
217
218 (define_attr "got" "unset,xgot_high,load"
219 (const_string "unset"))
220
221 ;; For jal instructions, this attribute is DIRECT when the target address
222 ;; is symbolic and INDIRECT when it is a register.
223 (define_attr "jal" "unset,direct,indirect"
224 (const_string "unset"))
225
226 ;; This attribute is YES if the instruction is a jal macro (not a
227 ;; real jal instruction).
228 ;;
229 ;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
230 ;; an instruction to restore $gp. Direct jals are also macros for
231 ;; flag_pic && !TARGET_ABSOLUTE_ABICALLS because they first load
232 ;; the target address into a register.
233 (define_attr "jal_macro" "no,yes"
234 (cond [(eq_attr "jal" "direct")
235 (symbol_ref "TARGET_CALL_CLOBBERED_GP
236 || (flag_pic && !TARGET_ABSOLUTE_ABICALLS)")
237 (eq_attr "jal" "indirect")
238 (symbol_ref "TARGET_CALL_CLOBBERED_GP")]
239 (const_string "no")))
240
241 ;; Classification of each insn.
242 ;; branch conditional branch
243 ;; jump unconditional jump
244 ;; call unconditional call
245 ;; load load instruction(s)
246 ;; fpload floating point load
247 ;; fpidxload floating point indexed load
248 ;; store store instruction(s)
249 ;; fpstore floating point store
250 ;; fpidxstore floating point indexed store
251 ;; prefetch memory prefetch (register + offset)
252 ;; prefetchx memory indexed prefetch (register + register)
253 ;; condmove conditional moves
254 ;; mfc transfer from coprocessor
255 ;; mtc transfer to coprocessor
256 ;; mthilo transfer to hi/lo registers
257 ;; mfhilo transfer from hi/lo registers
258 ;; const load constant
259 ;; arith integer arithmetic instructions
260 ;; logical integer logical instructions
261 ;; shift integer shift instructions
262 ;; slt set less than instructions
263 ;; signext sign extend instructions
264 ;; clz the clz and clo instructions
265 ;; trap trap if instructions
266 ;; imul integer multiply 2 operands
267 ;; imul3 integer multiply 3 operands
268 ;; imadd integer multiply-add
269 ;; idiv integer divide
270 ;; move integer register move ({,D}ADD{,U} with rt = 0)
271 ;; fmove floating point register move
272 ;; fadd floating point add/subtract
273 ;; fmul floating point multiply
274 ;; fmadd floating point multiply-add
275 ;; fdiv floating point divide
276 ;; frdiv floating point reciprocal divide
277 ;; frdiv1 floating point reciprocal divide step 1
278 ;; frdiv2 floating point reciprocal divide step 2
279 ;; fabs floating point absolute value
280 ;; fneg floating point negation
281 ;; fcmp floating point compare
282 ;; fcvt floating point convert
283 ;; fsqrt floating point square root
284 ;; frsqrt floating point reciprocal square root
285 ;; frsqrt1 floating point reciprocal square root step1
286 ;; frsqrt2 floating point reciprocal square root step2
287 ;; multi multiword sequence (or user asm statements)
288 ;; nop no operation
289 (define_attr "type"
290 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,mfc,mtc,mthilo,mfhilo,const,arith,logical,shift,slt,signext,clz,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
291 (cond [(eq_attr "jal" "!unset") (const_string "call")
292 (eq_attr "got" "load") (const_string "load")]
293 (const_string "unknown")))
294
295 ;; Main data type used by the insn
296 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
297 (const_string "unknown"))
298
299 ;; Mode for conversion types (fcvt)
300 ;; I2S integer to float single (SI/DI to SF)
301 ;; I2D integer to float double (SI/DI to DF)
302 ;; S2I float to integer (SF to SI/DI)
303 ;; D2I float to integer (DF to SI/DI)
304 ;; D2S double to float single
305 ;; S2D float single to double
306
307 (define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
308 (const_string "unknown"))
309
310 ;; Is this an extended instruction in mips16 mode?
311 (define_attr "extended_mips16" "no,yes"
312 (const_string "no"))
313
314 ;; Length of instruction in bytes.
315 (define_attr "length" ""
316 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
317 ;; If a branch is outside this range, we have a choice of two
318 ;; sequences. For PIC, an out-of-range branch like:
319 ;;
320 ;; bne r1,r2,target
321 ;; dslot
322 ;;
323 ;; becomes the equivalent of:
324 ;;
325 ;; beq r1,r2,1f
326 ;; dslot
327 ;; la $at,target
328 ;; jr $at
329 ;; nop
330 ;; 1:
331 ;;
332 ;; where the load address can be up to three instructions long
333 ;; (lw, nop, addiu).
334 ;;
335 ;; The non-PIC case is similar except that we use a direct
336 ;; jump instead of an la/jr pair. Since the target of this
337 ;; jump is an absolute 28-bit bit address (the other bits
338 ;; coming from the address of the delay slot) this form cannot
339 ;; cross a 256MB boundary. We could provide the option of
340 ;; using la/jr in this case too, but we do not do so at
341 ;; present.
342 ;;
343 ;; Note that this value does not account for the delay slot
344 ;; instruction, whose length is added separately. If the RTL
345 ;; pattern has no explicit delay slot, mips_adjust_insn_length
346 ;; will add the length of the implicit nop. The values for
347 ;; forward and backward branches will be different as well.
348 (eq_attr "type" "branch")
349 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
350 (le (minus (pc) (match_dup 1)) (const_int 131068)))
351 (const_int 4)
352 (ne (symbol_ref "flag_pic") (const_int 0))
353 (const_int 24)
354 ] (const_int 12))
355
356 (eq_attr "got" "load")
357 (const_int 4)
358 (eq_attr "got" "xgot_high")
359 (const_int 8)
360
361 (eq_attr "type" "const")
362 (symbol_ref "mips_const_insns (operands[1]) * 4")
363 (eq_attr "type" "load,fpload")
364 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
365 (eq_attr "type" "store,fpstore")
366 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
367
368 ;; In the worst case, a call macro will take 8 instructions:
369 ;;
370 ;; lui $25,%call_hi(FOO)
371 ;; addu $25,$25,$28
372 ;; lw $25,%call_lo(FOO)($25)
373 ;; nop
374 ;; jalr $25
375 ;; nop
376 ;; lw $gp,X($sp)
377 ;; nop
378 (eq_attr "jal_macro" "yes")
379 (const_int 32)
380
381 (and (eq_attr "extended_mips16" "yes")
382 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
383 (const_int 8)
384
385 ;; Various VR4120 errata require a nop to be inserted after a macc
386 ;; instruction. The assembler does this for us, so account for
387 ;; the worst-case length here.
388 (and (eq_attr "type" "imadd")
389 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
390 (const_int 8)
391
392 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
393 ;; the result of the second one is missed. The assembler should work
394 ;; around this by inserting a nop after the first dmult.
395 (and (eq_attr "type" "imul,imul3")
396 (and (eq_attr "mode" "DI")
397 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
398 (const_int 8)
399
400 (eq_attr "type" "idiv")
401 (symbol_ref "mips_idiv_insns () * 4")
402 ] (const_int 4)))
403
404 ;; Attribute describing the processor. This attribute must match exactly
405 ;; with the processor_type enumeration in mips.h.
406 (define_attr "cpu"
407 "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
408 (const (symbol_ref "mips_tune")))
409
410 ;; The type of hardware hazard associated with this instruction.
411 ;; DELAY means that the next instruction cannot read the result
412 ;; of this one. HILO means that the next two instructions cannot
413 ;; write to HI or LO.
414 (define_attr "hazard" "none,delay,hilo"
415 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
416 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
417 (const_string "delay")
418
419 (and (eq_attr "type" "mfc,mtc")
420 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
421 (const_string "delay")
422
423 (and (eq_attr "type" "fcmp")
424 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
425 (const_string "delay")
426
427 ;; The r4000 multiplication patterns include an mflo instruction.
428 (and (eq_attr "type" "imul")
429 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
430 (const_string "hilo")
431
432 (and (eq_attr "type" "mfhilo")
433 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
434 (const_string "hilo")]
435 (const_string "none")))
436
437 ;; Is it a single instruction?
438 (define_attr "single_insn" "no,yes"
439 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
440
441 ;; Can the instruction be put into a delay slot?
442 (define_attr "can_delay" "no,yes"
443 (if_then_else (and (eq_attr "type" "!branch,call,jump")
444 (and (eq_attr "hazard" "none")
445 (eq_attr "single_insn" "yes")))
446 (const_string "yes")
447 (const_string "no")))
448
449 ;; Attribute defining whether or not we can use the branch-likely instructions
450 (define_attr "branch_likely" "no,yes"
451 (const
452 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
453 (const_string "yes")
454 (const_string "no"))))
455
456 ;; True if an instruction might assign to hi or lo when reloaded.
457 ;; This is used by the TUNE_MACC_CHAINS code.
458 (define_attr "may_clobber_hilo" "no,yes"
459 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
460 (const_string "yes")
461 (const_string "no")))
462
463 ;; Describe a user's asm statement.
464 (define_asm_attributes
465 [(set_attr "type" "multi")
466 (set_attr "can_delay" "no")])
467 \f
468 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
469 ;; from the same template.
470 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
471
472 ;; This mode macro allows :P to be used for patterns that operate on
473 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
474 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
475
476 ;; This mode macro allows :MOVECC to be used anywhere that a
477 ;; conditional-move-type condition is needed.
478 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
479
480 ;; This mode macro allows the QI and HI extension patterns to be defined from
481 ;; the same template.
482 (define_mode_macro SHORT [QI HI])
483
484 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
485 ;; floating-point mode is allowed.
486 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
487 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
488 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
489
490 ;; Like ANYF, but only applies to scalar modes.
491 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
492 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
493
494 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
495 ;; 32-bit version and "dsubu" in the 64-bit version.
496 (define_mode_attr d [(SI "") (DI "d")])
497
498 ;; This attribute gives the length suffix for a sign- or zero-extension
499 ;; instruction.
500 (define_mode_attr size [(QI "b") (HI "h")])
501
502 ;; This attributes gives the mode mask of a SHORT.
503 (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
504
505 ;; Mode attributes for GPR loads and stores.
506 (define_mode_attr load [(SI "lw") (DI "ld")])
507 (define_mode_attr store [(SI "sw") (DI "sd")])
508
509 ;; Similarly for MIPS IV indexed FPR loads and stores.
510 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
511 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
512
513 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
514 ;; are different. Some forms of unextended addiu have an 8-bit immediate
515 ;; field but the equivalent daddiu has only a 5-bit field.
516 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
517
518 ;; This attribute gives the best constraint to use for registers of
519 ;; a given mode.
520 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
521
522 ;; This attribute gives the format suffix for floating-point operations.
523 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
524
525 ;; This attribute gives the upper-case mode name for one unit of a
526 ;; floating-point mode.
527 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
528
529 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
530 ;;
531 ;; In certain cases, div.s and div.ps may have a rounding error
532 ;; and/or wrong inexact flag.
533 ;;
534 ;; Therefore, we only allow div.s if not working around SB-1 rev2
535 ;; errata or if a slight loss of precision is OK.
536 (define_mode_attr divide_condition
537 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
538 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
539
540 ; This attribute gives the condition for which sqrt instructions exist.
541 (define_mode_attr sqrt_condition
542 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
543
544 ; This attribute gives the condition for which recip and rsqrt instructions
545 ; exist.
546 (define_mode_attr recip_condition
547 [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
548
549 ;; This code macro allows all branch instructions to be generated from
550 ;; a single define_expand template.
551 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
552 eq ne gt ge lt le gtu geu ltu leu])
553
554 ;; This code macro allows signed and unsigned widening multiplications
555 ;; to use the same template.
556 (define_code_macro any_extend [sign_extend zero_extend])
557
558 ;; This code macro allows the three shift instructions to be generated
559 ;; from the same template.
560 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
561
562 ;; This code macro allows all native floating-point comparisons to be
563 ;; generated from the same template.
564 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
565
566 ;; This code macro is used for comparisons that can be implemented
567 ;; by swapping the operands.
568 (define_code_macro swapped_fcond [ge gt unge ungt])
569
570 ;; <u> expands to an empty string when doing a signed operation and
571 ;; "u" when doing an unsigned operation.
572 (define_code_attr u [(sign_extend "") (zero_extend "u")])
573
574 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
575 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
576
577 ;; <optab> expands to the name of the optab for a particular code.
578 (define_code_attr optab [(ashift "ashl")
579 (ashiftrt "ashr")
580 (lshiftrt "lshr")])
581
582 ;; <insn> expands to the name of the insn that implements a particular code.
583 (define_code_attr insn [(ashift "sll")
584 (ashiftrt "sra")
585 (lshiftrt "srl")])
586
587 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
588 (define_code_attr fcond [(unordered "un")
589 (uneq "ueq")
590 (unlt "ult")
591 (unle "ule")
592 (eq "eq")
593 (lt "lt")
594 (le "le")])
595
596 ;; Similar, but for swapped conditions.
597 (define_code_attr swapped_fcond [(ge "le")
598 (gt "lt")
599 (unge "ule")
600 (ungt "ult")])
601 \f
602 ;; .........................
603 ;;
604 ;; Branch, call and jump delay slots
605 ;;
606 ;; .........................
607
608 (define_delay (and (eq_attr "type" "branch")
609 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
610 [(eq_attr "can_delay" "yes")
611 (nil)
612 (and (eq_attr "branch_likely" "yes")
613 (eq_attr "can_delay" "yes"))])
614
615 (define_delay (eq_attr "type" "jump")
616 [(eq_attr "can_delay" "yes")
617 (nil)
618 (nil)])
619
620 (define_delay (and (eq_attr "type" "call")
621 (eq_attr "jal_macro" "no"))
622 [(eq_attr "can_delay" "yes")
623 (nil)
624 (nil)])
625 \f
626 ;; Pipeline descriptions.
627 ;;
628 ;; generic.md provides a fallback for processors without a specific
629 ;; pipeline description. It is derived from the old define_function_unit
630 ;; version and uses the "alu" and "imuldiv" units declared below.
631 ;;
632 ;; Some of the processor-specific files are also derived from old
633 ;; define_function_unit descriptions and simply override the parts of
634 ;; generic.md that don't apply. The other processor-specific files
635 ;; are self-contained.
636 (define_automaton "alu,imuldiv")
637
638 (define_cpu_unit "alu" "alu")
639 (define_cpu_unit "imuldiv" "imuldiv")
640
641 (include "4k.md")
642 (include "5k.md")
643 (include "20kc.md")
644 (include "24k.md")
645 (include "74k.md")
646 (include "3000.md")
647 (include "4000.md")
648 (include "4100.md")
649 (include "4130.md")
650 (include "4300.md")
651 (include "4600.md")
652 (include "5000.md")
653 (include "5400.md")
654 (include "5500.md")
655 (include "6000.md")
656 (include "7000.md")
657 (include "9000.md")
658 (include "sb1.md")
659 (include "sr71k.md")
660 (include "generic.md")
661 \f
662 ;;
663 ;; ....................
664 ;;
665 ;; CONDITIONAL TRAPS
666 ;;
667 ;; ....................
668 ;;
669
670 (define_insn "trap"
671 [(trap_if (const_int 1) (const_int 0))]
672 ""
673 {
674 if (ISA_HAS_COND_TRAP)
675 return "teq\t$0,$0";
676 else if (TARGET_MIPS16)
677 return "break 0";
678 else
679 return "break";
680 }
681 [(set_attr "type" "trap")])
682
683 (define_expand "conditional_trap"
684 [(trap_if (match_operator 0 "comparison_operator"
685 [(match_dup 2) (match_dup 3)])
686 (match_operand 1 "const_int_operand"))]
687 "ISA_HAS_COND_TRAP"
688 {
689 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
690 && operands[1] == const0_rtx)
691 {
692 mips_gen_conditional_trap (operands);
693 DONE;
694 }
695 else
696 FAIL;
697 })
698
699 (define_insn "*conditional_trap<mode>"
700 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
701 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
702 (match_operand:GPR 2 "arith_operand" "dI")])
703 (const_int 0))]
704 "ISA_HAS_COND_TRAP"
705 "t%C0\t%z1,%2"
706 [(set_attr "type" "trap")])
707 \f
708 ;;
709 ;; ....................
710 ;;
711 ;; ADDITION
712 ;;
713 ;; ....................
714 ;;
715
716 (define_insn "add<mode>3"
717 [(set (match_operand:ANYF 0 "register_operand" "=f")
718 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
719 (match_operand:ANYF 2 "register_operand" "f")))]
720 ""
721 "add.<fmt>\t%0,%1,%2"
722 [(set_attr "type" "fadd")
723 (set_attr "mode" "<UNITMODE>")])
724
725 (define_expand "add<mode>3"
726 [(set (match_operand:GPR 0 "register_operand")
727 (plus:GPR (match_operand:GPR 1 "register_operand")
728 (match_operand:GPR 2 "arith_operand")))]
729 "")
730
731 (define_insn "*add<mode>3"
732 [(set (match_operand:GPR 0 "register_operand" "=d,d")
733 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
734 (match_operand:GPR 2 "arith_operand" "d,Q")))]
735 "!TARGET_MIPS16"
736 "@
737 <d>addu\t%0,%1,%2
738 <d>addiu\t%0,%1,%2"
739 [(set_attr "type" "arith")
740 (set_attr "mode" "<MODE>")])
741
742 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
743 ;; we don't have a constraint for $sp. These insns will be generated by
744 ;; the save_restore_insns functions.
745
746 (define_insn "*add<mode>3_sp1"
747 [(set (reg:GPR 29)
748 (plus:GPR (reg:GPR 29)
749 (match_operand:GPR 0 "const_arith_operand" "")))]
750 "TARGET_MIPS16"
751 "<d>addiu\t%$,%$,%0"
752 [(set_attr "type" "arith")
753 (set_attr "mode" "<MODE>")
754 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
755 (const_int 4)
756 (const_int 8)))])
757
758 (define_insn "*add<mode>3_sp2"
759 [(set (match_operand:GPR 0 "register_operand" "=d")
760 (plus:GPR (reg:GPR 29)
761 (match_operand:GPR 1 "const_arith_operand" "")))]
762 "TARGET_MIPS16"
763 "<d>addiu\t%0,%$,%1"
764 [(set_attr "type" "arith")
765 (set_attr "mode" "<MODE>")
766 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
767 (const_int 4)
768 (const_int 8)))])
769
770 (define_insn "*add<mode>3_mips16"
771 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
772 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
773 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
774 "TARGET_MIPS16"
775 "@
776 <d>addiu\t%0,%2
777 <d>addiu\t%0,%1,%2
778 <d>addu\t%0,%1,%2"
779 [(set_attr "type" "arith")
780 (set_attr "mode" "<MODE>")
781 (set_attr_alternative "length"
782 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
783 (const_int 4)
784 (const_int 8))
785 (if_then_else (match_operand 2 "m16_simm4_1")
786 (const_int 4)
787 (const_int 8))
788 (const_int 4)])])
789
790
791 ;; On the mips16, we can sometimes split an add of a constant which is
792 ;; a 4 byte instruction into two adds which are both 2 byte
793 ;; instructions. There are two cases: one where we are adding a
794 ;; constant plus a register to another register, and one where we are
795 ;; simply adding a constant to a register.
796
797 (define_split
798 [(set (match_operand:SI 0 "register_operand")
799 (plus:SI (match_dup 0)
800 (match_operand:SI 1 "const_int_operand")))]
801 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
802 && REG_P (operands[0])
803 && M16_REG_P (REGNO (operands[0]))
804 && GET_CODE (operands[1]) == CONST_INT
805 && ((INTVAL (operands[1]) > 0x7f
806 && INTVAL (operands[1]) <= 0x7f + 0x7f)
807 || (INTVAL (operands[1]) < - 0x80
808 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
809 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
810 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
811 {
812 HOST_WIDE_INT val = INTVAL (operands[1]);
813
814 if (val >= 0)
815 {
816 operands[1] = GEN_INT (0x7f);
817 operands[2] = GEN_INT (val - 0x7f);
818 }
819 else
820 {
821 operands[1] = GEN_INT (- 0x80);
822 operands[2] = GEN_INT (val + 0x80);
823 }
824 })
825
826 (define_split
827 [(set (match_operand:SI 0 "register_operand")
828 (plus:SI (match_operand:SI 1 "register_operand")
829 (match_operand:SI 2 "const_int_operand")))]
830 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
831 && REG_P (operands[0])
832 && M16_REG_P (REGNO (operands[0]))
833 && REG_P (operands[1])
834 && M16_REG_P (REGNO (operands[1]))
835 && REGNO (operands[0]) != REGNO (operands[1])
836 && GET_CODE (operands[2]) == CONST_INT
837 && ((INTVAL (operands[2]) > 0x7
838 && INTVAL (operands[2]) <= 0x7 + 0x7f)
839 || (INTVAL (operands[2]) < - 0x8
840 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
841 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
842 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
843 {
844 HOST_WIDE_INT val = INTVAL (operands[2]);
845
846 if (val >= 0)
847 {
848 operands[2] = GEN_INT (0x7);
849 operands[3] = GEN_INT (val - 0x7);
850 }
851 else
852 {
853 operands[2] = GEN_INT (- 0x8);
854 operands[3] = GEN_INT (val + 0x8);
855 }
856 })
857
858 (define_split
859 [(set (match_operand:DI 0 "register_operand")
860 (plus:DI (match_dup 0)
861 (match_operand:DI 1 "const_int_operand")))]
862 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
863 && REG_P (operands[0])
864 && M16_REG_P (REGNO (operands[0]))
865 && GET_CODE (operands[1]) == CONST_INT
866 && ((INTVAL (operands[1]) > 0xf
867 && INTVAL (operands[1]) <= 0xf + 0xf)
868 || (INTVAL (operands[1]) < - 0x10
869 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
870 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
871 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
872 {
873 HOST_WIDE_INT val = INTVAL (operands[1]);
874
875 if (val >= 0)
876 {
877 operands[1] = GEN_INT (0xf);
878 operands[2] = GEN_INT (val - 0xf);
879 }
880 else
881 {
882 operands[1] = GEN_INT (- 0x10);
883 operands[2] = GEN_INT (val + 0x10);
884 }
885 })
886
887 (define_split
888 [(set (match_operand:DI 0 "register_operand")
889 (plus:DI (match_operand:DI 1 "register_operand")
890 (match_operand:DI 2 "const_int_operand")))]
891 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
892 && REG_P (operands[0])
893 && M16_REG_P (REGNO (operands[0]))
894 && REG_P (operands[1])
895 && M16_REG_P (REGNO (operands[1]))
896 && REGNO (operands[0]) != REGNO (operands[1])
897 && GET_CODE (operands[2]) == CONST_INT
898 && ((INTVAL (operands[2]) > 0x7
899 && INTVAL (operands[2]) <= 0x7 + 0xf)
900 || (INTVAL (operands[2]) < - 0x8
901 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
902 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
903 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
904 {
905 HOST_WIDE_INT val = INTVAL (operands[2]);
906
907 if (val >= 0)
908 {
909 operands[2] = GEN_INT (0x7);
910 operands[3] = GEN_INT (val - 0x7);
911 }
912 else
913 {
914 operands[2] = GEN_INT (- 0x8);
915 operands[3] = GEN_INT (val + 0x8);
916 }
917 })
918
919 (define_insn "*addsi3_extended"
920 [(set (match_operand:DI 0 "register_operand" "=d,d")
921 (sign_extend:DI
922 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
923 (match_operand:SI 2 "arith_operand" "d,Q"))))]
924 "TARGET_64BIT && !TARGET_MIPS16"
925 "@
926 addu\t%0,%1,%2
927 addiu\t%0,%1,%2"
928 [(set_attr "type" "arith")
929 (set_attr "mode" "SI")])
930
931 ;; Split this insn so that the addiu splitters can have a crack at it.
932 ;; Use a conservative length estimate until the split.
933 (define_insn_and_split "*addsi3_extended_mips16"
934 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
935 (sign_extend:DI
936 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
937 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
938 "TARGET_64BIT && TARGET_MIPS16"
939 "#"
940 "&& reload_completed"
941 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
942 { operands[3] = gen_lowpart (SImode, operands[0]); }
943 [(set_attr "type" "arith")
944 (set_attr "mode" "SI")
945 (set_attr "extended_mips16" "yes")])
946 \f
947 ;;
948 ;; ....................
949 ;;
950 ;; SUBTRACTION
951 ;;
952 ;; ....................
953 ;;
954
955 (define_insn "sub<mode>3"
956 [(set (match_operand:ANYF 0 "register_operand" "=f")
957 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
958 (match_operand:ANYF 2 "register_operand" "f")))]
959 ""
960 "sub.<fmt>\t%0,%1,%2"
961 [(set_attr "type" "fadd")
962 (set_attr "mode" "<UNITMODE>")])
963
964 (define_insn "sub<mode>3"
965 [(set (match_operand:GPR 0 "register_operand" "=d")
966 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
967 (match_operand:GPR 2 "register_operand" "d")))]
968 ""
969 "<d>subu\t%0,%1,%2"
970 [(set_attr "type" "arith")
971 (set_attr "mode" "<MODE>")])
972
973 (define_insn "*subsi3_extended"
974 [(set (match_operand:DI 0 "register_operand" "=d")
975 (sign_extend:DI
976 (minus:SI (match_operand:SI 1 "register_operand" "d")
977 (match_operand:SI 2 "register_operand" "d"))))]
978 "TARGET_64BIT"
979 "subu\t%0,%1,%2"
980 [(set_attr "type" "arith")
981 (set_attr "mode" "DI")])
982 \f
983 ;;
984 ;; ....................
985 ;;
986 ;; MULTIPLICATION
987 ;;
988 ;; ....................
989 ;;
990
991 (define_expand "mul<mode>3"
992 [(set (match_operand:SCALARF 0 "register_operand")
993 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
994 (match_operand:SCALARF 2 "register_operand")))]
995 ""
996 "")
997
998 (define_insn "*mul<mode>3"
999 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1000 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1001 (match_operand:SCALARF 2 "register_operand" "f")))]
1002 "!TARGET_4300_MUL_FIX"
1003 "mul.<fmt>\t%0,%1,%2"
1004 [(set_attr "type" "fmul")
1005 (set_attr "mode" "<MODE>")])
1006
1007 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1008 ;; operands may corrupt immediately following multiplies. This is a
1009 ;; simple fix to insert NOPs.
1010
1011 (define_insn "*mul<mode>3_r4300"
1012 [(set (match_operand:SCALARF 0 "register_operand" "=f")
1013 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1014 (match_operand:SCALARF 2 "register_operand" "f")))]
1015 "TARGET_4300_MUL_FIX"
1016 "mul.<fmt>\t%0,%1,%2\;nop"
1017 [(set_attr "type" "fmul")
1018 (set_attr "mode" "<MODE>")
1019 (set_attr "length" "8")])
1020
1021 (define_insn "mulv2sf3"
1022 [(set (match_operand:V2SF 0 "register_operand" "=f")
1023 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
1024 (match_operand:V2SF 2 "register_operand" "f")))]
1025 "TARGET_PAIRED_SINGLE_FLOAT"
1026 "mul.ps\t%0,%1,%2"
1027 [(set_attr "type" "fmul")
1028 (set_attr "mode" "SF")])
1029
1030 ;; The original R4000 has a cpu bug. If a double-word or a variable
1031 ;; shift executes while an integer multiplication is in progress, the
1032 ;; shift may give an incorrect result. Avoid this by keeping the mflo
1033 ;; with the mult on the R4000.
1034 ;;
1035 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
1036 ;; (also valid for MIPS R4000MC processors):
1037 ;;
1038 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
1039 ;; this errata description.
1040 ;; The following code sequence causes the R4000 to incorrectly
1041 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
1042 ;; instruction. If the dsra32 instruction is executed during an
1043 ;; integer multiply, the dsra32 will only shift by the amount in
1044 ;; specified in the instruction rather than the amount plus 32
1045 ;; bits.
1046 ;; instruction 1: mult rs,rt integer multiply
1047 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
1048 ;; right arithmetic + 32
1049 ;; Workaround: A dsra32 instruction placed after an integer
1050 ;; multiply should not be one of the 11 instructions after the
1051 ;; multiply instruction."
1052 ;;
1053 ;; and:
1054 ;;
1055 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
1056 ;; the following description.
1057 ;; All extended shifts (shift by n+32) and variable shifts (32 and
1058 ;; 64-bit versions) may produce incorrect results under the
1059 ;; following conditions:
1060 ;; 1) An integer multiply is currently executing
1061 ;; 2) These types of shift instructions are executed immediately
1062 ;; following an integer divide instruction.
1063 ;; Workaround:
1064 ;; 1) Make sure no integer multiply is running wihen these
1065 ;; instruction are executed. If this cannot be predicted at
1066 ;; compile time, then insert a "mfhi" to R0 instruction
1067 ;; immediately after the integer multiply instruction. This
1068 ;; will cause the integer multiply to complete before the shift
1069 ;; is executed.
1070 ;; 2) Separate integer divide and these two classes of shift
1071 ;; instructions by another instruction or a noop."
1072 ;;
1073 ;; These processors have PRId values of 0x00004220 and 0x00004300,
1074 ;; respectively.
1075
1076 (define_expand "mulsi3"
1077 [(set (match_operand:SI 0 "register_operand")
1078 (mult:SI (match_operand:SI 1 "register_operand")
1079 (match_operand:SI 2 "register_operand")))]
1080 ""
1081 {
1082 if (ISA_HAS_MUL3)
1083 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1084 else if (TARGET_FIX_R4000)
1085 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1086 else
1087 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1088 DONE;
1089 })
1090
1091 (define_expand "muldi3"
1092 [(set (match_operand:DI 0 "register_operand")
1093 (mult:DI (match_operand:DI 1 "register_operand")
1094 (match_operand:DI 2 "register_operand")))]
1095 "TARGET_64BIT"
1096 {
1097 if (TARGET_FIX_R4000)
1098 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1099 else
1100 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1101 DONE;
1102 })
1103
1104 (define_insn "mulsi3_mult3"
1105 [(set (match_operand:SI 0 "register_operand" "=d,l")
1106 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1107 (match_operand:SI 2 "register_operand" "d,d")))
1108 (clobber (match_scratch:SI 3 "=h,h"))
1109 (clobber (match_scratch:SI 4 "=l,X"))]
1110 "ISA_HAS_MUL3"
1111 {
1112 if (which_alternative == 1)
1113 return "mult\t%1,%2";
1114 if (TARGET_MIPS3900)
1115 return "mult\t%0,%1,%2";
1116 return "mul\t%0,%1,%2";
1117 }
1118 [(set_attr "type" "imul3,imul")
1119 (set_attr "mode" "SI")])
1120
1121 ;; If a register gets allocated to LO, and we spill to memory, the reload
1122 ;; will include a move from LO to a GPR. Merge it into the multiplication
1123 ;; if it can set the GPR directly.
1124 ;;
1125 ;; Operand 0: LO
1126 ;; Operand 1: GPR (1st multiplication operand)
1127 ;; Operand 2: GPR (2nd multiplication operand)
1128 ;; Operand 3: HI
1129 ;; Operand 4: GPR (destination)
1130 (define_peephole2
1131 [(parallel
1132 [(set (match_operand:SI 0 "register_operand")
1133 (mult:SI (match_operand:SI 1 "register_operand")
1134 (match_operand:SI 2 "register_operand")))
1135 (clobber (match_operand:SI 3 "register_operand"))
1136 (clobber (scratch:SI))])
1137 (set (match_operand:SI 4 "register_operand")
1138 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1139 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])"
1140 [(parallel
1141 [(set (match_dup 4)
1142 (mult:SI (match_dup 1)
1143 (match_dup 2)))
1144 (clobber (match_dup 3))
1145 (clobber (match_dup 0))])])
1146
1147 (define_insn "mul<mode>3_internal"
1148 [(set (match_operand:GPR 0 "register_operand" "=l")
1149 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1150 (match_operand:GPR 2 "register_operand" "d")))
1151 (clobber (match_scratch:GPR 3 "=h"))]
1152 "!TARGET_FIX_R4000"
1153 "<d>mult\t%1,%2"
1154 [(set_attr "type" "imul")
1155 (set_attr "mode" "<MODE>")])
1156
1157 (define_insn "mul<mode>3_r4000"
1158 [(set (match_operand:GPR 0 "register_operand" "=d")
1159 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1160 (match_operand:GPR 2 "register_operand" "d")))
1161 (clobber (match_scratch:GPR 3 "=h"))
1162 (clobber (match_scratch:GPR 4 "=l"))]
1163 "TARGET_FIX_R4000"
1164 "<d>mult\t%1,%2\;mflo\t%0"
1165 [(set_attr "type" "imul")
1166 (set_attr "mode" "<MODE>")
1167 (set_attr "length" "8")])
1168
1169 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1170 ;; of "mult; mflo". They have the same latency, but the first form gives
1171 ;; us an extra cycle to compute the operands.
1172
1173 ;; Operand 0: LO
1174 ;; Operand 1: GPR (1st multiplication operand)
1175 ;; Operand 2: GPR (2nd multiplication operand)
1176 ;; Operand 3: HI
1177 ;; Operand 4: GPR (destination)
1178 (define_peephole2
1179 [(parallel
1180 [(set (match_operand:SI 0 "register_operand")
1181 (mult:SI (match_operand:SI 1 "register_operand")
1182 (match_operand:SI 2 "register_operand")))
1183 (clobber (match_operand:SI 3 "register_operand"))])
1184 (set (match_operand:SI 4 "register_operand")
1185 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1186 "ISA_HAS_MACC && !ISA_HAS_MUL3"
1187 [(set (match_dup 0)
1188 (const_int 0))
1189 (parallel
1190 [(set (match_dup 0)
1191 (plus:SI (mult:SI (match_dup 1)
1192 (match_dup 2))
1193 (match_dup 0)))
1194 (set (match_dup 4)
1195 (plus:SI (mult:SI (match_dup 1)
1196 (match_dup 2))
1197 (match_dup 0)))
1198 (clobber (match_dup 3))])])
1199
1200 ;; Multiply-accumulate patterns
1201
1202 ;; For processors that can copy the output to a general register:
1203 ;;
1204 ;; The all-d alternative is needed because the combiner will find this
1205 ;; pattern and then register alloc/reload will move registers around to
1206 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1207 ;;
1208 ;; The last alternative should be made slightly less desirable, but adding
1209 ;; "?" to the constraint is too strong, and causes values to be loaded into
1210 ;; LO even when that's more costly. For now, using "*d" mostly does the
1211 ;; trick.
1212 (define_insn "*mul_acc_si"
1213 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1214 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1215 (match_operand:SI 2 "register_operand" "d,d,d"))
1216 (match_operand:SI 3 "register_operand" "0,l,*d")))
1217 (clobber (match_scratch:SI 4 "=h,h,h"))
1218 (clobber (match_scratch:SI 5 "=X,3,l"))
1219 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1220 "(TARGET_MIPS3900
1221 || GENERATE_MADD_MSUB)
1222 && !TARGET_MIPS16"
1223 {
1224 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1225 if (which_alternative == 2)
1226 return "#";
1227 if (GENERATE_MADD_MSUB && which_alternative != 0)
1228 return "#";
1229 return madd[which_alternative];
1230 }
1231 [(set_attr "type" "imadd")
1232 (set_attr "mode" "SI")
1233 (set_attr "length" "4,4,8")])
1234
1235 ;; Split the above insn if we failed to get LO allocated.
1236 (define_split
1237 [(set (match_operand:SI 0 "register_operand")
1238 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1239 (match_operand:SI 2 "register_operand"))
1240 (match_operand:SI 3 "register_operand")))
1241 (clobber (match_scratch:SI 4))
1242 (clobber (match_scratch:SI 5))
1243 (clobber (match_scratch:SI 6))]
1244 "reload_completed && !TARGET_DEBUG_D_MODE
1245 && GP_REG_P (true_regnum (operands[0]))
1246 && GP_REG_P (true_regnum (operands[3]))"
1247 [(parallel [(set (match_dup 6)
1248 (mult:SI (match_dup 1) (match_dup 2)))
1249 (clobber (match_dup 4))
1250 (clobber (match_dup 5))])
1251 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1252 "")
1253
1254 ;; Splitter to copy result of MADD to a general register
1255 (define_split
1256 [(set (match_operand:SI 0 "register_operand")
1257 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1258 (match_operand:SI 2 "register_operand"))
1259 (match_operand:SI 3 "register_operand")))
1260 (clobber (match_scratch:SI 4))
1261 (clobber (match_scratch:SI 5))
1262 (clobber (match_scratch:SI 6))]
1263 "reload_completed && !TARGET_DEBUG_D_MODE
1264 && GP_REG_P (true_regnum (operands[0]))
1265 && true_regnum (operands[3]) == LO_REGNUM"
1266 [(parallel [(set (match_dup 3)
1267 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1268 (match_dup 3)))
1269 (clobber (match_dup 4))
1270 (clobber (match_dup 5))
1271 (clobber (match_dup 6))])
1272 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1273 "")
1274
1275 (define_insn "*macc"
1276 [(set (match_operand:SI 0 "register_operand" "=l,d")
1277 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1278 (match_operand:SI 2 "register_operand" "d,d"))
1279 (match_operand:SI 3 "register_operand" "0,l")))
1280 (clobber (match_scratch:SI 4 "=h,h"))
1281 (clobber (match_scratch:SI 5 "=X,3"))]
1282 "ISA_HAS_MACC"
1283 {
1284 if (which_alternative == 1)
1285 return "macc\t%0,%1,%2";
1286 else if (TARGET_MIPS5500)
1287 return "madd\t%1,%2";
1288 else
1289 /* The VR4130 assumes that there is a two-cycle latency between a macc
1290 that "writes" to $0 and an instruction that reads from it. We avoid
1291 this by assigning to $1 instead. */
1292 return "%[macc\t%@,%1,%2%]";
1293 }
1294 [(set_attr "type" "imadd")
1295 (set_attr "mode" "SI")])
1296
1297 (define_insn "*msac"
1298 [(set (match_operand:SI 0 "register_operand" "=l,d")
1299 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1300 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1301 (match_operand:SI 3 "register_operand" "d,d"))))
1302 (clobber (match_scratch:SI 4 "=h,h"))
1303 (clobber (match_scratch:SI 5 "=X,1"))]
1304 "ISA_HAS_MSAC"
1305 {
1306 if (which_alternative == 1)
1307 return "msac\t%0,%2,%3";
1308 else if (TARGET_MIPS5500)
1309 return "msub\t%2,%3";
1310 else
1311 return "msac\t$0,%2,%3";
1312 }
1313 [(set_attr "type" "imadd")
1314 (set_attr "mode" "SI")])
1315
1316 ;; An msac-like instruction implemented using negation and a macc.
1317 (define_insn_and_split "*msac_using_macc"
1318 [(set (match_operand:SI 0 "register_operand" "=l,d")
1319 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1320 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1321 (match_operand:SI 3 "register_operand" "d,d"))))
1322 (clobber (match_scratch:SI 4 "=h,h"))
1323 (clobber (match_scratch:SI 5 "=X,1"))
1324 (clobber (match_scratch:SI 6 "=d,d"))]
1325 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1326 "#"
1327 "&& reload_completed"
1328 [(set (match_dup 6)
1329 (neg:SI (match_dup 3)))
1330 (parallel
1331 [(set (match_dup 0)
1332 (plus:SI (mult:SI (match_dup 2)
1333 (match_dup 6))
1334 (match_dup 1)))
1335 (clobber (match_dup 4))
1336 (clobber (match_dup 5))])]
1337 ""
1338 [(set_attr "type" "imadd")
1339 (set_attr "length" "8")])
1340
1341 ;; Patterns generated by the define_peephole2 below.
1342
1343 (define_insn "*macc2"
1344 [(set (match_operand:SI 0 "register_operand" "=l")
1345 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1346 (match_operand:SI 2 "register_operand" "d"))
1347 (match_dup 0)))
1348 (set (match_operand:SI 3 "register_operand" "=d")
1349 (plus:SI (mult:SI (match_dup 1)
1350 (match_dup 2))
1351 (match_dup 0)))
1352 (clobber (match_scratch:SI 4 "=h"))]
1353 "ISA_HAS_MACC && reload_completed"
1354 "macc\t%3,%1,%2"
1355 [(set_attr "type" "imadd")
1356 (set_attr "mode" "SI")])
1357
1358 (define_insn "*msac2"
1359 [(set (match_operand:SI 0 "register_operand" "=l")
1360 (minus:SI (match_dup 0)
1361 (mult:SI (match_operand:SI 1 "register_operand" "d")
1362 (match_operand:SI 2 "register_operand" "d"))))
1363 (set (match_operand:SI 3 "register_operand" "=d")
1364 (minus:SI (match_dup 0)
1365 (mult:SI (match_dup 1)
1366 (match_dup 2))))
1367 (clobber (match_scratch:SI 4 "=h"))]
1368 "ISA_HAS_MSAC && reload_completed"
1369 "msac\t%3,%1,%2"
1370 [(set_attr "type" "imadd")
1371 (set_attr "mode" "SI")])
1372
1373 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1374 ;; Similarly msac.
1375 ;;
1376 ;; Operand 0: LO
1377 ;; Operand 1: macc/msac
1378 ;; Operand 2: HI
1379 ;; Operand 3: GPR (destination)
1380 (define_peephole2
1381 [(parallel
1382 [(set (match_operand:SI 0 "register_operand")
1383 (match_operand:SI 1 "macc_msac_operand"))
1384 (clobber (match_operand:SI 2 "register_operand"))
1385 (clobber (scratch:SI))])
1386 (set (match_operand:SI 3 "register_operand")
1387 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1388 ""
1389 [(parallel [(set (match_dup 0)
1390 (match_dup 1))
1391 (set (match_dup 3)
1392 (match_dup 1))
1393 (clobber (match_dup 2))])]
1394 "")
1395
1396 ;; When we have a three-address multiplication instruction, it should
1397 ;; be faster to do a separate multiply and add, rather than moving
1398 ;; something into LO in order to use a macc instruction.
1399 ;;
1400 ;; This peephole needs a scratch register to cater for the case when one
1401 ;; of the multiplication operands is the same as the destination.
1402 ;;
1403 ;; Operand 0: GPR (scratch)
1404 ;; Operand 1: LO
1405 ;; Operand 2: GPR (addend)
1406 ;; Operand 3: GPR (destination)
1407 ;; Operand 4: macc/msac
1408 ;; Operand 5: HI
1409 ;; Operand 6: new multiplication
1410 ;; Operand 7: new addition/subtraction
1411 (define_peephole2
1412 [(match_scratch:SI 0 "d")
1413 (set (match_operand:SI 1 "register_operand")
1414 (match_operand:SI 2 "register_operand"))
1415 (match_dup 0)
1416 (parallel
1417 [(set (match_operand:SI 3 "register_operand")
1418 (match_operand:SI 4 "macc_msac_operand"))
1419 (clobber (match_operand:SI 5 "register_operand"))
1420 (clobber (match_dup 1))])]
1421 "ISA_HAS_MUL3
1422 && true_regnum (operands[1]) == LO_REGNUM
1423 && peep2_reg_dead_p (2, operands[1])
1424 && GP_REG_P (true_regnum (operands[3]))"
1425 [(parallel [(set (match_dup 0)
1426 (match_dup 6))
1427 (clobber (match_dup 5))
1428 (clobber (match_dup 1))])
1429 (set (match_dup 3)
1430 (match_dup 7))]
1431 {
1432 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1433 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1434 operands[2], operands[0]);
1435 })
1436
1437 ;; Same as above, except LO is the initial target of the macc.
1438 ;;
1439 ;; Operand 0: GPR (scratch)
1440 ;; Operand 1: LO
1441 ;; Operand 2: GPR (addend)
1442 ;; Operand 3: macc/msac
1443 ;; Operand 4: HI
1444 ;; Operand 5: GPR (destination)
1445 ;; Operand 6: new multiplication
1446 ;; Operand 7: new addition/subtraction
1447 (define_peephole2
1448 [(match_scratch:SI 0 "d")
1449 (set (match_operand:SI 1 "register_operand")
1450 (match_operand:SI 2 "register_operand"))
1451 (match_dup 0)
1452 (parallel
1453 [(set (match_dup 1)
1454 (match_operand:SI 3 "macc_msac_operand"))
1455 (clobber (match_operand:SI 4 "register_operand"))
1456 (clobber (scratch:SI))])
1457 (match_dup 0)
1458 (set (match_operand:SI 5 "register_operand")
1459 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1460 "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])"
1461 [(parallel [(set (match_dup 0)
1462 (match_dup 6))
1463 (clobber (match_dup 4))
1464 (clobber (match_dup 1))])
1465 (set (match_dup 5)
1466 (match_dup 7))]
1467 {
1468 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1469 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1470 operands[2], operands[0]);
1471 })
1472
1473 (define_insn "*mul_sub_si"
1474 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1475 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1476 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1477 (match_operand:SI 3 "register_operand" "d,d,d"))))
1478 (clobber (match_scratch:SI 4 "=h,h,h"))
1479 (clobber (match_scratch:SI 5 "=X,1,l"))
1480 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1481 "GENERATE_MADD_MSUB"
1482 "@
1483 msub\t%2,%3
1484 #
1485 #"
1486 [(set_attr "type" "imadd")
1487 (set_attr "mode" "SI")
1488 (set_attr "length" "4,8,8")])
1489
1490 ;; Split the above insn if we failed to get LO allocated.
1491 (define_split
1492 [(set (match_operand:SI 0 "register_operand")
1493 (minus:SI (match_operand:SI 1 "register_operand")
1494 (mult:SI (match_operand:SI 2 "register_operand")
1495 (match_operand:SI 3 "register_operand"))))
1496 (clobber (match_scratch:SI 4))
1497 (clobber (match_scratch:SI 5))
1498 (clobber (match_scratch:SI 6))]
1499 "reload_completed && !TARGET_DEBUG_D_MODE
1500 && GP_REG_P (true_regnum (operands[0]))
1501 && GP_REG_P (true_regnum (operands[1]))"
1502 [(parallel [(set (match_dup 6)
1503 (mult:SI (match_dup 2) (match_dup 3)))
1504 (clobber (match_dup 4))
1505 (clobber (match_dup 5))])
1506 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1507 "")
1508
1509 ;; Splitter to copy result of MSUB to a general register
1510 (define_split
1511 [(set (match_operand:SI 0 "register_operand")
1512 (minus:SI (match_operand:SI 1 "register_operand")
1513 (mult:SI (match_operand:SI 2 "register_operand")
1514 (match_operand:SI 3 "register_operand"))))
1515 (clobber (match_scratch:SI 4))
1516 (clobber (match_scratch:SI 5))
1517 (clobber (match_scratch:SI 6))]
1518 "reload_completed && !TARGET_DEBUG_D_MODE
1519 && GP_REG_P (true_regnum (operands[0]))
1520 && true_regnum (operands[1]) == LO_REGNUM"
1521 [(parallel [(set (match_dup 1)
1522 (minus:SI (match_dup 1)
1523 (mult:SI (match_dup 2) (match_dup 3))))
1524 (clobber (match_dup 4))
1525 (clobber (match_dup 5))
1526 (clobber (match_dup 6))])
1527 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1528 "")
1529
1530 (define_insn "*muls"
1531 [(set (match_operand:SI 0 "register_operand" "=l,d")
1532 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1533 (match_operand:SI 2 "register_operand" "d,d"))))
1534 (clobber (match_scratch:SI 3 "=h,h"))
1535 (clobber (match_scratch:SI 4 "=X,l"))]
1536 "ISA_HAS_MULS"
1537 "@
1538 muls\t$0,%1,%2
1539 muls\t%0,%1,%2"
1540 [(set_attr "type" "imul,imul3")
1541 (set_attr "mode" "SI")])
1542
1543 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1544
1545 (define_expand "<u>mulsidi3"
1546 [(parallel
1547 [(set (match_operand:DI 0 "register_operand")
1548 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1549 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1550 (clobber (scratch:DI))
1551 (clobber (scratch:DI))
1552 (clobber (scratch:DI))])]
1553 "!TARGET_64BIT || !TARGET_FIX_R4000"
1554 {
1555 if (!TARGET_64BIT)
1556 {
1557 if (!TARGET_FIX_R4000)
1558 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1559 operands[2]));
1560 else
1561 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1562 operands[2]));
1563 DONE;
1564 }
1565 })
1566
1567 (define_insn "<u>mulsidi3_32bit_internal"
1568 [(set (match_operand:DI 0 "register_operand" "=x")
1569 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1570 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1571 "!TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_DSPR2"
1572 "mult<u>\t%1,%2"
1573 [(set_attr "type" "imul")
1574 (set_attr "mode" "SI")])
1575
1576 (define_insn "<u>mulsidi3_32bit_r4000"
1577 [(set (match_operand:DI 0 "register_operand" "=d")
1578 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1579 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1580 (clobber (match_scratch:DI 3 "=x"))]
1581 "!TARGET_64BIT && TARGET_FIX_R4000"
1582 "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1583 [(set_attr "type" "imul")
1584 (set_attr "mode" "SI")
1585 (set_attr "length" "12")])
1586
1587 (define_insn_and_split "*<u>mulsidi3_64bit"
1588 [(set (match_operand:DI 0 "register_operand" "=d")
1589 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1590 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1591 (clobber (match_scratch:DI 3 "=l"))
1592 (clobber (match_scratch:DI 4 "=h"))
1593 (clobber (match_scratch:DI 5 "=d"))]
1594 "TARGET_64BIT && !TARGET_FIX_R4000"
1595 "#"
1596 "&& reload_completed"
1597 [(parallel
1598 [(set (match_dup 3)
1599 (sign_extend:DI
1600 (mult:SI (match_dup 1)
1601 (match_dup 2))))
1602 (set (match_dup 4)
1603 (ashiftrt:DI
1604 (mult:DI (any_extend:DI (match_dup 1))
1605 (any_extend:DI (match_dup 2)))
1606 (const_int 32)))])
1607
1608 ;; OP5 <- LO, OP0 <- HI
1609 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1610 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1611
1612 ;; Zero-extend OP5.
1613 (set (match_dup 5)
1614 (ashift:DI (match_dup 5)
1615 (const_int 32)))
1616 (set (match_dup 5)
1617 (lshiftrt:DI (match_dup 5)
1618 (const_int 32)))
1619
1620 ;; Shift OP0 into place.
1621 (set (match_dup 0)
1622 (ashift:DI (match_dup 0)
1623 (const_int 32)))
1624
1625 ;; OR the two halves together
1626 (set (match_dup 0)
1627 (ior:DI (match_dup 0)
1628 (match_dup 5)))]
1629 ""
1630 [(set_attr "type" "imul")
1631 (set_attr "mode" "SI")
1632 (set_attr "length" "24")])
1633
1634 (define_insn "*<u>mulsidi3_64bit_parts"
1635 [(set (match_operand:DI 0 "register_operand" "=l")
1636 (sign_extend:DI
1637 (mult:SI (match_operand:SI 2 "register_operand" "d")
1638 (match_operand:SI 3 "register_operand" "d"))))
1639 (set (match_operand:DI 1 "register_operand" "=h")
1640 (ashiftrt:DI
1641 (mult:DI (any_extend:DI (match_dup 2))
1642 (any_extend:DI (match_dup 3)))
1643 (const_int 32)))]
1644 "TARGET_64BIT && !TARGET_FIX_R4000"
1645 "mult<u>\t%2,%3"
1646 [(set_attr "type" "imul")
1647 (set_attr "mode" "SI")])
1648
1649 ;; Widening multiply with negation.
1650 (define_insn "*muls<u>_di"
1651 [(set (match_operand:DI 0 "register_operand" "=x")
1652 (neg:DI
1653 (mult:DI
1654 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1655 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1656 "!TARGET_64BIT && ISA_HAS_MULS"
1657 "muls<u>\t$0,%1,%2"
1658 [(set_attr "type" "imul")
1659 (set_attr "mode" "SI")])
1660
1661 (define_insn "<u>msubsidi4"
1662 [(set (match_operand:DI 0 "register_operand" "=ka")
1663 (minus:DI
1664 (match_operand:DI 3 "register_operand" "0")
1665 (mult:DI
1666 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1667 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1668 "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || TARGET_DSPR2)"
1669 {
1670 if (TARGET_DSPR2)
1671 return "msub<u>\t%q0,%1,%2";
1672 else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB)
1673 return "msub<u>\t%1,%2";
1674 else
1675 return "msac<u>\t$0,%1,%2";
1676 }
1677 [(set_attr "type" "imadd")
1678 (set_attr "mode" "SI")])
1679
1680 ;; _highpart patterns
1681
1682 (define_expand "<su>mulsi3_highpart"
1683 [(set (match_operand:SI 0 "register_operand")
1684 (truncate:SI
1685 (lshiftrt:DI
1686 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1687 (any_extend:DI (match_operand:SI 2 "register_operand")))
1688 (const_int 32))))]
1689 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1690 {
1691 if (ISA_HAS_MULHI)
1692 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1693 operands[1],
1694 operands[2]));
1695 else
1696 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1697 operands[2]));
1698 DONE;
1699 })
1700
1701 (define_insn "<su>mulsi3_highpart_internal"
1702 [(set (match_operand:SI 0 "register_operand" "=h")
1703 (truncate:SI
1704 (lshiftrt:DI
1705 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1706 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1707 (const_int 32))))
1708 (clobber (match_scratch:SI 3 "=l"))]
1709 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1710 "mult<u>\t%1,%2"
1711 [(set_attr "type" "imul")
1712 (set_attr "mode" "SI")])
1713
1714 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1715 [(set (match_operand:SI 0 "register_operand" "=h,d")
1716 (truncate:SI
1717 (lshiftrt:DI
1718 (mult:DI
1719 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1720 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1721 (const_int 32))))
1722 (clobber (match_scratch:SI 3 "=l,l"))
1723 (clobber (match_scratch:SI 4 "=X,h"))]
1724 "ISA_HAS_MULHI"
1725 "@
1726 mult<u>\t%1,%2
1727 mulhi<u>\t%0,%1,%2"
1728 [(set_attr "type" "imul,imul3")
1729 (set_attr "mode" "SI")])
1730
1731 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1732 [(set (match_operand:SI 0 "register_operand" "=h,d")
1733 (truncate:SI
1734 (lshiftrt:DI
1735 (neg:DI
1736 (mult:DI
1737 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1738 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1739 (const_int 32))))
1740 (clobber (match_scratch:SI 3 "=l,l"))
1741 (clobber (match_scratch:SI 4 "=X,h"))]
1742 "ISA_HAS_MULHI"
1743 "@
1744 mulshi<u>\t%.,%1,%2
1745 mulshi<u>\t%0,%1,%2"
1746 [(set_attr "type" "imul,imul3")
1747 (set_attr "mode" "SI")])
1748
1749 ;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1750 ;; errata MD(0), which says that dmultu does not always produce the
1751 ;; correct result.
1752 (define_insn "<su>muldi3_highpart"
1753 [(set (match_operand:DI 0 "register_operand" "=h")
1754 (truncate:DI
1755 (lshiftrt:TI
1756 (mult:TI
1757 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1758 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1759 (const_int 64))))
1760 (clobber (match_scratch:DI 3 "=l"))]
1761 "TARGET_64BIT && !TARGET_FIX_R4000
1762 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1763 "dmult<u>\t%1,%2"
1764 [(set_attr "type" "imul")
1765 (set_attr "mode" "DI")])
1766
1767 ;; The R4650 supports a 32-bit multiply/ 64-bit accumulate
1768 ;; instruction. The HI/LO registers are used as a 64-bit accumulator.
1769
1770 (define_insn "madsi"
1771 [(set (match_operand:SI 0 "register_operand" "+l")
1772 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1773 (match_operand:SI 2 "register_operand" "d"))
1774 (match_dup 0)))
1775 (clobber (match_scratch:SI 3 "=h"))]
1776 "TARGET_MAD"
1777 "mad\t%1,%2"
1778 [(set_attr "type" "imadd")
1779 (set_attr "mode" "SI")])
1780
1781 (define_insn "<u>maddsidi4"
1782 [(set (match_operand:DI 0 "register_operand" "=ka")
1783 (plus:DI
1784 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1785 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1786 (match_operand:DI 3 "register_operand" "0")))]
1787 "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || TARGET_DSPR2)
1788 && !TARGET_64BIT"
1789 {
1790 if (TARGET_MAD)
1791 return "mad<u>\t%1,%2";
1792 else if (TARGET_DSPR2)
1793 return "madd<u>\t%q0,%1,%2";
1794 else if (GENERATE_MADD_MSUB || TARGET_MIPS5500)
1795 return "madd<u>\t%1,%2";
1796 else
1797 /* See comment in *macc. */
1798 return "%[macc<u>\t%@,%1,%2%]";
1799 }
1800 [(set_attr "type" "imadd")
1801 (set_attr "mode" "SI")])
1802
1803 ;; Floating point multiply accumulate instructions.
1804
1805 (define_insn "*madd<mode>"
1806 [(set (match_operand:ANYF 0 "register_operand" "=f")
1807 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1808 (match_operand:ANYF 2 "register_operand" "f"))
1809 (match_operand:ANYF 3 "register_operand" "f")))]
1810 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1811 "madd.<fmt>\t%0,%3,%1,%2"
1812 [(set_attr "type" "fmadd")
1813 (set_attr "mode" "<UNITMODE>")])
1814
1815 (define_insn "*msub<mode>"
1816 [(set (match_operand:ANYF 0 "register_operand" "=f")
1817 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1818 (match_operand:ANYF 2 "register_operand" "f"))
1819 (match_operand:ANYF 3 "register_operand" "f")))]
1820 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1821 "msub.<fmt>\t%0,%3,%1,%2"
1822 [(set_attr "type" "fmadd")
1823 (set_attr "mode" "<UNITMODE>")])
1824
1825 (define_insn "*nmadd<mode>"
1826 [(set (match_operand:ANYF 0 "register_operand" "=f")
1827 (neg:ANYF (plus:ANYF
1828 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1829 (match_operand:ANYF 2 "register_operand" "f"))
1830 (match_operand:ANYF 3 "register_operand" "f"))))]
1831 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1832 && HONOR_SIGNED_ZEROS (<MODE>mode)
1833 && !HONOR_NANS (<MODE>mode)"
1834 "nmadd.<fmt>\t%0,%3,%1,%2"
1835 [(set_attr "type" "fmadd")
1836 (set_attr "mode" "<UNITMODE>")])
1837
1838 (define_insn "*nmadd<mode>_fastmath"
1839 [(set (match_operand:ANYF 0 "register_operand" "=f")
1840 (minus:ANYF
1841 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1842 (match_operand:ANYF 2 "register_operand" "f"))
1843 (match_operand:ANYF 3 "register_operand" "f")))]
1844 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1845 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1846 && !HONOR_NANS (<MODE>mode)"
1847 "nmadd.<fmt>\t%0,%3,%1,%2"
1848 [(set_attr "type" "fmadd")
1849 (set_attr "mode" "<UNITMODE>")])
1850
1851 (define_insn "*nmsub<mode>"
1852 [(set (match_operand:ANYF 0 "register_operand" "=f")
1853 (neg:ANYF (minus:ANYF
1854 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1855 (match_operand:ANYF 3 "register_operand" "f"))
1856 (match_operand:ANYF 1 "register_operand" "f"))))]
1857 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1858 && HONOR_SIGNED_ZEROS (<MODE>mode)
1859 && !HONOR_NANS (<MODE>mode)"
1860 "nmsub.<fmt>\t%0,%1,%2,%3"
1861 [(set_attr "type" "fmadd")
1862 (set_attr "mode" "<UNITMODE>")])
1863
1864 (define_insn "*nmsub<mode>_fastmath"
1865 [(set (match_operand:ANYF 0 "register_operand" "=f")
1866 (minus:ANYF
1867 (match_operand:ANYF 1 "register_operand" "f")
1868 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1869 (match_operand:ANYF 3 "register_operand" "f"))))]
1870 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1871 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1872 && !HONOR_NANS (<MODE>mode)"
1873 "nmsub.<fmt>\t%0,%1,%2,%3"
1874 [(set_attr "type" "fmadd")
1875 (set_attr "mode" "<UNITMODE>")])
1876 \f
1877 ;;
1878 ;; ....................
1879 ;;
1880 ;; DIVISION and REMAINDER
1881 ;;
1882 ;; ....................
1883 ;;
1884
1885 (define_expand "div<mode>3"
1886 [(set (match_operand:ANYF 0 "register_operand")
1887 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1888 (match_operand:ANYF 2 "register_operand")))]
1889 "<divide_condition>"
1890 {
1891 if (const_1_operand (operands[1], <MODE>mode))
1892 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1893 operands[1] = force_reg (<MODE>mode, operands[1]);
1894 })
1895
1896 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1897 ;;
1898 ;; If an mfc1 or dmfc1 happens to access the floating point register
1899 ;; file at the same time a long latency operation (div, sqrt, recip,
1900 ;; sqrt) iterates an intermediate result back through the floating
1901 ;; point register file bypass, then instead returning the correct
1902 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1903 ;; result of the long latency operation.
1904 ;;
1905 ;; The workaround is to insert an unconditional 'mov' from/to the
1906 ;; long latency op destination register.
1907
1908 (define_insn "*div<mode>3"
1909 [(set (match_operand:ANYF 0 "register_operand" "=f")
1910 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1911 (match_operand:ANYF 2 "register_operand" "f")))]
1912 "<divide_condition>"
1913 {
1914 if (TARGET_FIX_SB1)
1915 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1916 else
1917 return "div.<fmt>\t%0,%1,%2";
1918 }
1919 [(set_attr "type" "fdiv")
1920 (set_attr "mode" "<UNITMODE>")
1921 (set (attr "length")
1922 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1923 (const_int 8)
1924 (const_int 4)))])
1925
1926 (define_insn "*recip<mode>3"
1927 [(set (match_operand:ANYF 0 "register_operand" "=f")
1928 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1929 (match_operand:ANYF 2 "register_operand" "f")))]
1930 "<recip_condition> && flag_unsafe_math_optimizations"
1931 {
1932 if (TARGET_FIX_SB1)
1933 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1934 else
1935 return "recip.<fmt>\t%0,%2";
1936 }
1937 [(set_attr "type" "frdiv")
1938 (set_attr "mode" "<UNITMODE>")
1939 (set (attr "length")
1940 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1941 (const_int 8)
1942 (const_int 4)))])
1943
1944 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1945 ;; with negative operands. We use special libgcc functions instead.
1946 (define_insn "divmod<mode>4"
1947 [(set (match_operand:GPR 0 "register_operand" "=l")
1948 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1949 (match_operand:GPR 2 "register_operand" "d")))
1950 (set (match_operand:GPR 3 "register_operand" "=h")
1951 (mod:GPR (match_dup 1)
1952 (match_dup 2)))]
1953 "!TARGET_FIX_VR4120"
1954 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1955 [(set_attr "type" "idiv")
1956 (set_attr "mode" "<MODE>")])
1957
1958 (define_insn "udivmod<mode>4"
1959 [(set (match_operand:GPR 0 "register_operand" "=l")
1960 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1961 (match_operand:GPR 2 "register_operand" "d")))
1962 (set (match_operand:GPR 3 "register_operand" "=h")
1963 (umod:GPR (match_dup 1)
1964 (match_dup 2)))]
1965 ""
1966 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1967 [(set_attr "type" "idiv")
1968 (set_attr "mode" "<MODE>")])
1969 \f
1970 ;;
1971 ;; ....................
1972 ;;
1973 ;; SQUARE ROOT
1974 ;;
1975 ;; ....................
1976
1977 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1978 ;; "*div[sd]f3" comment for details).
1979
1980 (define_insn "sqrt<mode>2"
1981 [(set (match_operand:ANYF 0 "register_operand" "=f")
1982 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1983 "<sqrt_condition>"
1984 {
1985 if (TARGET_FIX_SB1)
1986 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1987 else
1988 return "sqrt.<fmt>\t%0,%1";
1989 }
1990 [(set_attr "type" "fsqrt")
1991 (set_attr "mode" "<UNITMODE>")
1992 (set (attr "length")
1993 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1994 (const_int 8)
1995 (const_int 4)))])
1996
1997 (define_insn "*rsqrt<mode>a"
1998 [(set (match_operand:ANYF 0 "register_operand" "=f")
1999 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2000 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
2001 "<recip_condition> && flag_unsafe_math_optimizations"
2002 {
2003 if (TARGET_FIX_SB1)
2004 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2005 else
2006 return "rsqrt.<fmt>\t%0,%2";
2007 }
2008 [(set_attr "type" "frsqrt")
2009 (set_attr "mode" "<UNITMODE>")
2010 (set (attr "length")
2011 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2012 (const_int 8)
2013 (const_int 4)))])
2014
2015 (define_insn "*rsqrt<mode>b"
2016 [(set (match_operand:ANYF 0 "register_operand" "=f")
2017 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
2018 (match_operand:ANYF 2 "register_operand" "f"))))]
2019 "<recip_condition> && flag_unsafe_math_optimizations"
2020 {
2021 if (TARGET_FIX_SB1)
2022 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
2023 else
2024 return "rsqrt.<fmt>\t%0,%2";
2025 }
2026 [(set_attr "type" "frsqrt")
2027 (set_attr "mode" "<UNITMODE>")
2028 (set (attr "length")
2029 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2030 (const_int 8)
2031 (const_int 4)))])
2032 \f
2033 ;;
2034 ;; ....................
2035 ;;
2036 ;; ABSOLUTE VALUE
2037 ;;
2038 ;; ....................
2039
2040 ;; Do not use the integer abs macro instruction, since that signals an
2041 ;; exception on -2147483648 (sigh).
2042
2043 ;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
2044 ;; invalid; it does not clear their sign bits. We therefore can't use
2045 ;; abs.fmt if the signs of NaNs matter.
2046
2047 (define_insn "abs<mode>2"
2048 [(set (match_operand:ANYF 0 "register_operand" "=f")
2049 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2050 "!HONOR_NANS (<MODE>mode)"
2051 "abs.<fmt>\t%0,%1"
2052 [(set_attr "type" "fabs")
2053 (set_attr "mode" "<UNITMODE>")])
2054 \f
2055 ;;
2056 ;; ...................
2057 ;;
2058 ;; Count leading zeroes.
2059 ;;
2060 ;; ...................
2061 ;;
2062
2063 (define_insn "clz<mode>2"
2064 [(set (match_operand:GPR 0 "register_operand" "=d")
2065 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2066 "ISA_HAS_CLZ_CLO"
2067 "<d>clz\t%0,%1"
2068 [(set_attr "type" "clz")
2069 (set_attr "mode" "<MODE>")])
2070 \f
2071 ;;
2072 ;; ....................
2073 ;;
2074 ;; NEGATION and ONE'S COMPLEMENT
2075 ;;
2076 ;; ....................
2077
2078 (define_insn "negsi2"
2079 [(set (match_operand:SI 0 "register_operand" "=d")
2080 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2081 ""
2082 {
2083 if (TARGET_MIPS16)
2084 return "neg\t%0,%1";
2085 else
2086 return "subu\t%0,%.,%1";
2087 }
2088 [(set_attr "type" "arith")
2089 (set_attr "mode" "SI")])
2090
2091 (define_insn "negdi2"
2092 [(set (match_operand:DI 0 "register_operand" "=d")
2093 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2094 "TARGET_64BIT && !TARGET_MIPS16"
2095 "dsubu\t%0,%.,%1"
2096 [(set_attr "type" "arith")
2097 (set_attr "mode" "DI")])
2098
2099 ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2100 ;; invalid; it does not flip their sign bit. We therefore can't use
2101 ;; neg.fmt if the signs of NaNs matter.
2102
2103 (define_insn "neg<mode>2"
2104 [(set (match_operand:ANYF 0 "register_operand" "=f")
2105 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2106 "!HONOR_NANS (<MODE>mode)"
2107 "neg.<fmt>\t%0,%1"
2108 [(set_attr "type" "fneg")
2109 (set_attr "mode" "<UNITMODE>")])
2110
2111 (define_insn "one_cmpl<mode>2"
2112 [(set (match_operand:GPR 0 "register_operand" "=d")
2113 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2114 ""
2115 {
2116 if (TARGET_MIPS16)
2117 return "not\t%0,%1";
2118 else
2119 return "nor\t%0,%.,%1";
2120 }
2121 [(set_attr "type" "logical")
2122 (set_attr "mode" "<MODE>")])
2123 \f
2124 ;;
2125 ;; ....................
2126 ;;
2127 ;; LOGICAL
2128 ;;
2129 ;; ....................
2130 ;;
2131
2132 ;; Many of these instructions use trivial define_expands, because we
2133 ;; want to use a different set of constraints when TARGET_MIPS16.
2134
2135 (define_expand "and<mode>3"
2136 [(set (match_operand:GPR 0 "register_operand")
2137 (and:GPR (match_operand:GPR 1 "register_operand")
2138 (match_operand:GPR 2 "uns_arith_operand")))]
2139 ""
2140 {
2141 if (TARGET_MIPS16)
2142 operands[2] = force_reg (<MODE>mode, operands[2]);
2143 })
2144
2145 (define_insn "*and<mode>3"
2146 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2147 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2148 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2149 "!TARGET_MIPS16"
2150 "@
2151 and\t%0,%1,%2
2152 andi\t%0,%1,%x2"
2153 [(set_attr "type" "logical")
2154 (set_attr "mode" "<MODE>")])
2155
2156 (define_insn "*and<mode>3_mips16"
2157 [(set (match_operand:GPR 0 "register_operand" "=d")
2158 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2159 (match_operand:GPR 2 "register_operand" "d")))]
2160 "TARGET_MIPS16"
2161 "and\t%0,%2"
2162 [(set_attr "type" "logical")
2163 (set_attr "mode" "<MODE>")])
2164
2165 (define_expand "ior<mode>3"
2166 [(set (match_operand:GPR 0 "register_operand")
2167 (ior:GPR (match_operand:GPR 1 "register_operand")
2168 (match_operand:GPR 2 "uns_arith_operand")))]
2169 ""
2170 {
2171 if (TARGET_MIPS16)
2172 operands[2] = force_reg (<MODE>mode, operands[2]);
2173 })
2174
2175 (define_insn "*ior<mode>3"
2176 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2177 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2178 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2179 "!TARGET_MIPS16"
2180 "@
2181 or\t%0,%1,%2
2182 ori\t%0,%1,%x2"
2183 [(set_attr "type" "logical")
2184 (set_attr "mode" "<MODE>")])
2185
2186 (define_insn "*ior<mode>3_mips16"
2187 [(set (match_operand:GPR 0 "register_operand" "=d")
2188 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2189 (match_operand:GPR 2 "register_operand" "d")))]
2190 "TARGET_MIPS16"
2191 "or\t%0,%2"
2192 [(set_attr "type" "logical")
2193 (set_attr "mode" "<MODE>")])
2194
2195 (define_expand "xor<mode>3"
2196 [(set (match_operand:GPR 0 "register_operand")
2197 (xor:GPR (match_operand:GPR 1 "register_operand")
2198 (match_operand:GPR 2 "uns_arith_operand")))]
2199 ""
2200 "")
2201
2202 (define_insn ""
2203 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2204 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2205 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2206 "!TARGET_MIPS16"
2207 "@
2208 xor\t%0,%1,%2
2209 xori\t%0,%1,%x2"
2210 [(set_attr "type" "logical")
2211 (set_attr "mode" "<MODE>")])
2212
2213 (define_insn ""
2214 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2215 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2216 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2217 "TARGET_MIPS16"
2218 "@
2219 xor\t%0,%2
2220 cmpi\t%1,%2
2221 cmp\t%1,%2"
2222 [(set_attr "type" "logical,arith,arith")
2223 (set_attr "mode" "<MODE>")
2224 (set_attr_alternative "length"
2225 [(const_int 4)
2226 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2227 (const_int 4)
2228 (const_int 8))
2229 (const_int 4)])])
2230
2231 (define_insn "*nor<mode>3"
2232 [(set (match_operand:GPR 0 "register_operand" "=d")
2233 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2234 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2235 "!TARGET_MIPS16"
2236 "nor\t%0,%1,%2"
2237 [(set_attr "type" "logical")
2238 (set_attr "mode" "<MODE>")])
2239 \f
2240 ;;
2241 ;; ....................
2242 ;;
2243 ;; TRUNCATION
2244 ;;
2245 ;; ....................
2246
2247
2248
2249 (define_insn "truncdfsf2"
2250 [(set (match_operand:SF 0 "register_operand" "=f")
2251 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2252 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2253 "cvt.s.d\t%0,%1"
2254 [(set_attr "type" "fcvt")
2255 (set_attr "cnv_mode" "D2S")
2256 (set_attr "mode" "SF")])
2257
2258 ;; Integer truncation patterns. Truncating SImode values to smaller
2259 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2260 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2261 ;; need to make sure that the lower 32 bits are properly sign-extended
2262 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2263 ;; smaller than SImode is equivalent to two separate truncations:
2264 ;;
2265 ;; A B
2266 ;; DI ---> HI == DI ---> SI ---> HI
2267 ;; DI ---> QI == DI ---> SI ---> QI
2268 ;;
2269 ;; Step A needs a real instruction but step B does not.
2270
2271 (define_insn "truncdisi2"
2272 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2273 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2274 "TARGET_64BIT"
2275 "@
2276 sll\t%0,%1,0
2277 sw\t%1,%0"
2278 [(set_attr "type" "shift,store")
2279 (set_attr "mode" "SI")
2280 (set_attr "extended_mips16" "yes,*")])
2281
2282 (define_insn "truncdihi2"
2283 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2284 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2285 "TARGET_64BIT"
2286 "@
2287 sll\t%0,%1,0
2288 sh\t%1,%0"
2289 [(set_attr "type" "shift,store")
2290 (set_attr "mode" "SI")
2291 (set_attr "extended_mips16" "yes,*")])
2292
2293 (define_insn "truncdiqi2"
2294 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2295 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2296 "TARGET_64BIT"
2297 "@
2298 sll\t%0,%1,0
2299 sb\t%1,%0"
2300 [(set_attr "type" "shift,store")
2301 (set_attr "mode" "SI")
2302 (set_attr "extended_mips16" "yes,*")])
2303
2304 ;; Combiner patterns to optimize shift/truncate combinations.
2305
2306 (define_insn ""
2307 [(set (match_operand:SI 0 "register_operand" "=d")
2308 (truncate:SI
2309 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2310 (match_operand:DI 2 "const_arith_operand" ""))))]
2311 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2312 "dsra\t%0,%1,%2"
2313 [(set_attr "type" "shift")
2314 (set_attr "mode" "SI")])
2315
2316 (define_insn ""
2317 [(set (match_operand:SI 0 "register_operand" "=d")
2318 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2319 (const_int 32))))]
2320 "TARGET_64BIT && !TARGET_MIPS16"
2321 "dsra\t%0,%1,32"
2322 [(set_attr "type" "shift")
2323 (set_attr "mode" "SI")])
2324
2325
2326 ;; Combiner patterns for truncate/sign_extend combinations. They use
2327 ;; the shift/truncate patterns above.
2328
2329 (define_insn_and_split ""
2330 [(set (match_operand:SI 0 "register_operand" "=d")
2331 (sign_extend:SI
2332 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2333 "TARGET_64BIT && !TARGET_MIPS16"
2334 "#"
2335 "&& reload_completed"
2336 [(set (match_dup 2)
2337 (ashift:DI (match_dup 1)
2338 (const_int 48)))
2339 (set (match_dup 0)
2340 (truncate:SI (ashiftrt:DI (match_dup 2)
2341 (const_int 48))))]
2342 { operands[2] = gen_lowpart (DImode, operands[0]); })
2343
2344 (define_insn_and_split ""
2345 [(set (match_operand:SI 0 "register_operand" "=d")
2346 (sign_extend:SI
2347 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2348 "TARGET_64BIT && !TARGET_MIPS16"
2349 "#"
2350 "&& reload_completed"
2351 [(set (match_dup 2)
2352 (ashift:DI (match_dup 1)
2353 (const_int 56)))
2354 (set (match_dup 0)
2355 (truncate:SI (ashiftrt:DI (match_dup 2)
2356 (const_int 56))))]
2357 { operands[2] = gen_lowpart (DImode, operands[0]); })
2358
2359
2360 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2361
2362 (define_insn ""
2363 [(set (match_operand:SI 0 "register_operand" "=d")
2364 (zero_extend:SI (truncate:HI
2365 (match_operand:DI 1 "register_operand" "d"))))]
2366 "TARGET_64BIT && !TARGET_MIPS16"
2367 "andi\t%0,%1,0xffff"
2368 [(set_attr "type" "logical")
2369 (set_attr "mode" "SI")])
2370
2371 (define_insn ""
2372 [(set (match_operand:SI 0 "register_operand" "=d")
2373 (zero_extend:SI (truncate:QI
2374 (match_operand:DI 1 "register_operand" "d"))))]
2375 "TARGET_64BIT && !TARGET_MIPS16"
2376 "andi\t%0,%1,0xff"
2377 [(set_attr "type" "logical")
2378 (set_attr "mode" "SI")])
2379
2380 (define_insn ""
2381 [(set (match_operand:HI 0 "register_operand" "=d")
2382 (zero_extend:HI (truncate:QI
2383 (match_operand:DI 1 "register_operand" "d"))))]
2384 "TARGET_64BIT && !TARGET_MIPS16"
2385 "andi\t%0,%1,0xff"
2386 [(set_attr "type" "logical")
2387 (set_attr "mode" "HI")])
2388 \f
2389 ;;
2390 ;; ....................
2391 ;;
2392 ;; ZERO EXTENSION
2393 ;;
2394 ;; ....................
2395
2396 ;; Extension insns.
2397
2398 (define_insn_and_split "zero_extendsidi2"
2399 [(set (match_operand:DI 0 "register_operand" "=d,d")
2400 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2401 "TARGET_64BIT"
2402 "@
2403 #
2404 lwu\t%0,%1"
2405 "&& reload_completed && REG_P (operands[1])"
2406 [(set (match_dup 0)
2407 (ashift:DI (match_dup 1) (const_int 32)))
2408 (set (match_dup 0)
2409 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2410 { operands[1] = gen_lowpart (DImode, operands[1]); }
2411 [(set_attr "type" "multi,load")
2412 (set_attr "mode" "DI")
2413 (set_attr "length" "8,*")])
2414
2415 ;; Combine is not allowed to convert this insn into a zero_extendsidi2
2416 ;; because of TRULY_NOOP_TRUNCATION.
2417
2418 (define_insn_and_split "*clear_upper32"
2419 [(set (match_operand:DI 0 "register_operand" "=d,d")
2420 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2421 (const_int 4294967295)))]
2422 "TARGET_64BIT"
2423 {
2424 if (which_alternative == 0)
2425 return "#";
2426
2427 operands[1] = gen_lowpart (SImode, operands[1]);
2428 return "lwu\t%0,%1";
2429 }
2430 "&& reload_completed && REG_P (operands[1])"
2431 [(set (match_dup 0)
2432 (ashift:DI (match_dup 1) (const_int 32)))
2433 (set (match_dup 0)
2434 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2435 ""
2436 [(set_attr "type" "multi,load")
2437 (set_attr "mode" "DI")
2438 (set_attr "length" "8,*")])
2439
2440 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2441 [(set (match_operand:GPR 0 "register_operand")
2442 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2443 ""
2444 {
2445 if (TARGET_MIPS16 && !GENERATE_MIPS16E
2446 && !memory_operand (operands[1], <SHORT:MODE>mode))
2447 {
2448 emit_insn (gen_and<GPR:mode>3 (operands[0],
2449 gen_lowpart (<GPR:MODE>mode, operands[1]),
2450 force_reg (<GPR:MODE>mode,
2451 GEN_INT (<SHORT:mask>))));
2452 DONE;
2453 }
2454 })
2455
2456 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2457 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2458 (zero_extend:GPR
2459 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2460 "!TARGET_MIPS16"
2461 "@
2462 andi\t%0,%1,<SHORT:mask>
2463 l<SHORT:size>u\t%0,%1"
2464 [(set_attr "type" "logical,load")
2465 (set_attr "mode" "<GPR:MODE>")])
2466
2467 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2468 [(set (match_operand:GPR 0 "register_operand" "=d")
2469 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2470 "GENERATE_MIPS16E"
2471 "ze<SHORT:size>\t%0"
2472 [(set_attr "type" "arith")
2473 (set_attr "mode" "<GPR:MODE>")])
2474
2475 (define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2476 [(set (match_operand:GPR 0 "register_operand" "=d")
2477 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2478 "TARGET_MIPS16"
2479 "l<SHORT:size>u\t%0,%1"
2480 [(set_attr "type" "load")
2481 (set_attr "mode" "<GPR:MODE>")])
2482
2483 (define_expand "zero_extendqihi2"
2484 [(set (match_operand:HI 0 "register_operand")
2485 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2486 ""
2487 {
2488 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2489 {
2490 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2491 operands[1]));
2492 DONE;
2493 }
2494 })
2495
2496 (define_insn "*zero_extendqihi2"
2497 [(set (match_operand:HI 0 "register_operand" "=d,d")
2498 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2499 "!TARGET_MIPS16"
2500 "@
2501 andi\t%0,%1,0x00ff
2502 lbu\t%0,%1"
2503 [(set_attr "type" "logical,load")
2504 (set_attr "mode" "HI")])
2505
2506 (define_insn "*zero_extendqihi2_mips16"
2507 [(set (match_operand:HI 0 "register_operand" "=d")
2508 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2509 "TARGET_MIPS16"
2510 "lbu\t%0,%1"
2511 [(set_attr "type" "load")
2512 (set_attr "mode" "HI")])
2513 \f
2514 ;;
2515 ;; ....................
2516 ;;
2517 ;; SIGN EXTENSION
2518 ;;
2519 ;; ....................
2520
2521 ;; Extension insns.
2522 ;; Those for integer source operand are ordered widest source type first.
2523
2524 ;; When TARGET_64BIT, all SImode integer registers should already be in
2525 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2526 ;; therefore get rid of register->register instructions if we constrain
2527 ;; the source to be in the same register as the destination.
2528 ;;
2529 ;; The register alternative has type "arith" so that the pre-reload
2530 ;; scheduler will treat it as a move. This reflects what happens if
2531 ;; the register alternative needs a reload.
2532 (define_insn_and_split "extendsidi2"
2533 [(set (match_operand:DI 0 "register_operand" "=d,d")
2534 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2535 "TARGET_64BIT"
2536 "@
2537 #
2538 lw\t%0,%1"
2539 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2540 [(const_int 0)]
2541 {
2542 emit_note (NOTE_INSN_DELETED);
2543 DONE;
2544 }
2545 [(set_attr "type" "arith,load")
2546 (set_attr "mode" "DI")])
2547
2548 (define_expand "extend<SHORT:mode><GPR:mode>2"
2549 [(set (match_operand:GPR 0 "register_operand")
2550 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2551 "")
2552
2553 (define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2554 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2555 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2556 "GENERATE_MIPS16E"
2557 "@
2558 se<SHORT:size>\t%0
2559 l<SHORT:size>\t%0,%1"
2560 [(set_attr "type" "signext,load")
2561 (set_attr "mode" "<GPR:MODE>")])
2562
2563 (define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2564 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2565 (sign_extend:GPR
2566 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2567 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2568 "@
2569 #
2570 l<SHORT:size>\t%0,%1"
2571 "&& reload_completed && REG_P (operands[1])"
2572 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2573 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2574 {
2575 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2576 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2577 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2578 }
2579 [(set_attr "type" "arith,load")
2580 (set_attr "mode" "<GPR:MODE>")
2581 (set_attr "length" "8,*")])
2582
2583 (define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2584 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2585 (sign_extend:GPR
2586 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2587 "ISA_HAS_SEB_SEH"
2588 "@
2589 se<SHORT:size>\t%0,%1
2590 l<SHORT:size>\t%0,%1"
2591 [(set_attr "type" "signext,load")
2592 (set_attr "mode" "<GPR:MODE>")])
2593
2594 (define_expand "extendqihi2"
2595 [(set (match_operand:HI 0 "register_operand")
2596 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2597 "")
2598
2599 (define_insn "*extendqihi2_mips16e"
2600 [(set (match_operand:HI 0 "register_operand" "=d,d")
2601 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))]
2602 "GENERATE_MIPS16E"
2603 "@
2604 seb\t%0
2605 lb\t%0,%1"
2606 [(set_attr "type" "signext,load")
2607 (set_attr "mode" "SI")])
2608
2609 (define_insn_and_split "*extendqihi2"
2610 [(set (match_operand:HI 0 "register_operand" "=d,d")
2611 (sign_extend:HI
2612 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2613 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2614 "@
2615 #
2616 lb\t%0,%1"
2617 "&& reload_completed && REG_P (operands[1])"
2618 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2619 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
2620 {
2621 operands[0] = gen_lowpart (SImode, operands[0]);
2622 operands[1] = gen_lowpart (SImode, operands[1]);
2623 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode)
2624 - GET_MODE_BITSIZE (QImode));
2625 }
2626 [(set_attr "type" "multi,load")
2627 (set_attr "mode" "SI")
2628 (set_attr "length" "8,*")])
2629
2630 (define_insn "*extendqihi2_seb"
2631 [(set (match_operand:HI 0 "register_operand" "=d,d")
2632 (sign_extend:HI
2633 (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2634 "ISA_HAS_SEB_SEH"
2635 "@
2636 seb\t%0,%1
2637 lb\t%0,%1"
2638 [(set_attr "type" "signext,load")
2639 (set_attr "mode" "SI")])
2640
2641 (define_insn "extendsfdf2"
2642 [(set (match_operand:DF 0 "register_operand" "=f")
2643 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2644 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2645 "cvt.d.s\t%0,%1"
2646 [(set_attr "type" "fcvt")
2647 (set_attr "cnv_mode" "S2D")
2648 (set_attr "mode" "DF")])
2649 \f
2650 ;;
2651 ;; ....................
2652 ;;
2653 ;; CONVERSIONS
2654 ;;
2655 ;; ....................
2656
2657 (define_expand "fix_truncdfsi2"
2658 [(set (match_operand:SI 0 "register_operand")
2659 (fix:SI (match_operand:DF 1 "register_operand")))]
2660 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2661 {
2662 if (!ISA_HAS_TRUNC_W)
2663 {
2664 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2665 DONE;
2666 }
2667 })
2668
2669 (define_insn "fix_truncdfsi2_insn"
2670 [(set (match_operand:SI 0 "register_operand" "=f")
2671 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2672 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2673 "trunc.w.d %0,%1"
2674 [(set_attr "type" "fcvt")
2675 (set_attr "mode" "DF")
2676 (set_attr "cnv_mode" "D2I")
2677 (set_attr "length" "4")])
2678
2679 (define_insn "fix_truncdfsi2_macro"
2680 [(set (match_operand:SI 0 "register_operand" "=f")
2681 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2682 (clobber (match_scratch:DF 2 "=d"))]
2683 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2684 {
2685 if (set_nomacro)
2686 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2687 else
2688 return "trunc.w.d %0,%1,%2";
2689 }
2690 [(set_attr "type" "fcvt")
2691 (set_attr "mode" "DF")
2692 (set_attr "cnv_mode" "D2I")
2693 (set_attr "length" "36")])
2694
2695 (define_expand "fix_truncsfsi2"
2696 [(set (match_operand:SI 0 "register_operand")
2697 (fix:SI (match_operand:SF 1 "register_operand")))]
2698 "TARGET_HARD_FLOAT"
2699 {
2700 if (!ISA_HAS_TRUNC_W)
2701 {
2702 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2703 DONE;
2704 }
2705 })
2706
2707 (define_insn "fix_truncsfsi2_insn"
2708 [(set (match_operand:SI 0 "register_operand" "=f")
2709 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2710 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2711 "trunc.w.s %0,%1"
2712 [(set_attr "type" "fcvt")
2713 (set_attr "mode" "SF")
2714 (set_attr "cnv_mode" "S2I")
2715 (set_attr "length" "4")])
2716
2717 (define_insn "fix_truncsfsi2_macro"
2718 [(set (match_operand:SI 0 "register_operand" "=f")
2719 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2720 (clobber (match_scratch:SF 2 "=d"))]
2721 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2722 {
2723 if (set_nomacro)
2724 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2725 else
2726 return "trunc.w.s %0,%1,%2";
2727 }
2728 [(set_attr "type" "fcvt")
2729 (set_attr "mode" "SF")
2730 (set_attr "cnv_mode" "S2I")
2731 (set_attr "length" "36")])
2732
2733
2734 (define_insn "fix_truncdfdi2"
2735 [(set (match_operand:DI 0 "register_operand" "=f")
2736 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2737 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2738 "trunc.l.d %0,%1"
2739 [(set_attr "type" "fcvt")
2740 (set_attr "mode" "DF")
2741 (set_attr "cnv_mode" "D2I")
2742 (set_attr "length" "4")])
2743
2744
2745 (define_insn "fix_truncsfdi2"
2746 [(set (match_operand:DI 0 "register_operand" "=f")
2747 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2748 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2749 "trunc.l.s %0,%1"
2750 [(set_attr "type" "fcvt")
2751 (set_attr "mode" "SF")
2752 (set_attr "cnv_mode" "S2I")
2753 (set_attr "length" "4")])
2754
2755
2756 (define_insn "floatsidf2"
2757 [(set (match_operand:DF 0 "register_operand" "=f")
2758 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2759 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2760 "cvt.d.w\t%0,%1"
2761 [(set_attr "type" "fcvt")
2762 (set_attr "mode" "DF")
2763 (set_attr "cnv_mode" "I2D")
2764 (set_attr "length" "4")])
2765
2766
2767 (define_insn "floatdidf2"
2768 [(set (match_operand:DF 0 "register_operand" "=f")
2769 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2770 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2771 "cvt.d.l\t%0,%1"
2772 [(set_attr "type" "fcvt")
2773 (set_attr "mode" "DF")
2774 (set_attr "cnv_mode" "I2D")
2775 (set_attr "length" "4")])
2776
2777
2778 (define_insn "floatsisf2"
2779 [(set (match_operand:SF 0 "register_operand" "=f")
2780 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2781 "TARGET_HARD_FLOAT"
2782 "cvt.s.w\t%0,%1"
2783 [(set_attr "type" "fcvt")
2784 (set_attr "mode" "SF")
2785 (set_attr "cnv_mode" "I2S")
2786 (set_attr "length" "4")])
2787
2788
2789 (define_insn "floatdisf2"
2790 [(set (match_operand:SF 0 "register_operand" "=f")
2791 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2792 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2793 "cvt.s.l\t%0,%1"
2794 [(set_attr "type" "fcvt")
2795 (set_attr "mode" "SF")
2796 (set_attr "cnv_mode" "I2S")
2797 (set_attr "length" "4")])
2798
2799
2800 (define_expand "fixuns_truncdfsi2"
2801 [(set (match_operand:SI 0 "register_operand")
2802 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2803 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2804 {
2805 rtx reg1 = gen_reg_rtx (DFmode);
2806 rtx reg2 = gen_reg_rtx (DFmode);
2807 rtx reg3 = gen_reg_rtx (SImode);
2808 rtx label1 = gen_label_rtx ();
2809 rtx label2 = gen_label_rtx ();
2810 REAL_VALUE_TYPE offset;
2811
2812 real_2expN (&offset, 31);
2813
2814 if (reg1) /* Turn off complaints about unreached code. */
2815 {
2816 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2817 do_pending_stack_adjust ();
2818
2819 emit_insn (gen_cmpdf (operands[1], reg1));
2820 emit_jump_insn (gen_bge (label1));
2821
2822 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2823 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2824 gen_rtx_LABEL_REF (VOIDmode, label2)));
2825 emit_barrier ();
2826
2827 emit_label (label1);
2828 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2829 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2830 (BITMASK_HIGH, SImode)));
2831
2832 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2833 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2834
2835 emit_label (label2);
2836
2837 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2838 fields, and can't be used for REG_NOTES anyway). */
2839 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2840 DONE;
2841 }
2842 })
2843
2844
2845 (define_expand "fixuns_truncdfdi2"
2846 [(set (match_operand:DI 0 "register_operand")
2847 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2848 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2849 {
2850 rtx reg1 = gen_reg_rtx (DFmode);
2851 rtx reg2 = gen_reg_rtx (DFmode);
2852 rtx reg3 = gen_reg_rtx (DImode);
2853 rtx label1 = gen_label_rtx ();
2854 rtx label2 = gen_label_rtx ();
2855 REAL_VALUE_TYPE offset;
2856
2857 real_2expN (&offset, 63);
2858
2859 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2860 do_pending_stack_adjust ();
2861
2862 emit_insn (gen_cmpdf (operands[1], reg1));
2863 emit_jump_insn (gen_bge (label1));
2864
2865 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2866 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2867 gen_rtx_LABEL_REF (VOIDmode, label2)));
2868 emit_barrier ();
2869
2870 emit_label (label1);
2871 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2872 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2873 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2874
2875 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2876 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2877
2878 emit_label (label2);
2879
2880 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2881 fields, and can't be used for REG_NOTES anyway). */
2882 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2883 DONE;
2884 })
2885
2886
2887 (define_expand "fixuns_truncsfsi2"
2888 [(set (match_operand:SI 0 "register_operand")
2889 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2890 "TARGET_HARD_FLOAT"
2891 {
2892 rtx reg1 = gen_reg_rtx (SFmode);
2893 rtx reg2 = gen_reg_rtx (SFmode);
2894 rtx reg3 = gen_reg_rtx (SImode);
2895 rtx label1 = gen_label_rtx ();
2896 rtx label2 = gen_label_rtx ();
2897 REAL_VALUE_TYPE offset;
2898
2899 real_2expN (&offset, 31);
2900
2901 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2902 do_pending_stack_adjust ();
2903
2904 emit_insn (gen_cmpsf (operands[1], reg1));
2905 emit_jump_insn (gen_bge (label1));
2906
2907 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2908 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2909 gen_rtx_LABEL_REF (VOIDmode, label2)));
2910 emit_barrier ();
2911
2912 emit_label (label1);
2913 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2914 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2915 (BITMASK_HIGH, SImode)));
2916
2917 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2918 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2919
2920 emit_label (label2);
2921
2922 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2923 fields, and can't be used for REG_NOTES anyway). */
2924 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2925 DONE;
2926 })
2927
2928
2929 (define_expand "fixuns_truncsfdi2"
2930 [(set (match_operand:DI 0 "register_operand")
2931 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2932 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2933 {
2934 rtx reg1 = gen_reg_rtx (SFmode);
2935 rtx reg2 = gen_reg_rtx (SFmode);
2936 rtx reg3 = gen_reg_rtx (DImode);
2937 rtx label1 = gen_label_rtx ();
2938 rtx label2 = gen_label_rtx ();
2939 REAL_VALUE_TYPE offset;
2940
2941 real_2expN (&offset, 63);
2942
2943 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2944 do_pending_stack_adjust ();
2945
2946 emit_insn (gen_cmpsf (operands[1], reg1));
2947 emit_jump_insn (gen_bge (label1));
2948
2949 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2950 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2951 gen_rtx_LABEL_REF (VOIDmode, label2)));
2952 emit_barrier ();
2953
2954 emit_label (label1);
2955 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2956 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2957 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2958
2959 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2960 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2961
2962 emit_label (label2);
2963
2964 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2965 fields, and can't be used for REG_NOTES anyway). */
2966 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2967 DONE;
2968 })
2969 \f
2970 ;;
2971 ;; ....................
2972 ;;
2973 ;; DATA MOVEMENT
2974 ;;
2975 ;; ....................
2976
2977 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2978
2979 (define_expand "extv"
2980 [(set (match_operand 0 "register_operand")
2981 (sign_extract (match_operand:QI 1 "memory_operand")
2982 (match_operand 2 "immediate_operand")
2983 (match_operand 3 "immediate_operand")))]
2984 "!TARGET_MIPS16"
2985 {
2986 if (mips_expand_unaligned_load (operands[0], operands[1],
2987 INTVAL (operands[2]),
2988 INTVAL (operands[3])))
2989 DONE;
2990 else
2991 FAIL;
2992 })
2993
2994 (define_expand "extzv"
2995 [(set (match_operand 0 "register_operand")
2996 (zero_extract (match_operand 1 "nonimmediate_operand")
2997 (match_operand 2 "immediate_operand")
2998 (match_operand 3 "immediate_operand")))]
2999 "!TARGET_MIPS16"
3000 {
3001 if (mips_expand_unaligned_load (operands[0], operands[1],
3002 INTVAL (operands[2]),
3003 INTVAL (operands[3])))
3004 DONE;
3005 else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
3006 {
3007 if (GET_MODE (operands[0]) == DImode)
3008 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
3009 operands[3]));
3010 else
3011 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
3012 operands[3]));
3013 DONE;
3014 }
3015 else
3016 FAIL;
3017 })
3018
3019 (define_insn "extzv<mode>"
3020 [(set (match_operand:GPR 0 "register_operand" "=d")
3021 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
3022 (match_operand:SI 2 "immediate_operand" "I")
3023 (match_operand:SI 3 "immediate_operand" "I")))]
3024 "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
3025 "<d>ext\t%0,%1,%3,%2"
3026 [(set_attr "type" "arith")
3027 (set_attr "mode" "<MODE>")])
3028
3029
3030 (define_expand "insv"
3031 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
3032 (match_operand 1 "immediate_operand")
3033 (match_operand 2 "immediate_operand"))
3034 (match_operand 3 "reg_or_0_operand"))]
3035 "!TARGET_MIPS16"
3036 {
3037 if (mips_expand_unaligned_store (operands[0], operands[3],
3038 INTVAL (operands[1]),
3039 INTVAL (operands[2])))
3040 DONE;
3041 else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
3042 {
3043 if (GET_MODE (operands[0]) == DImode)
3044 emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
3045 operands[3]));
3046 else
3047 emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
3048 operands[3]));
3049 DONE;
3050 }
3051 else
3052 FAIL;
3053 })
3054
3055 (define_insn "insv<mode>"
3056 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
3057 (match_operand:SI 1 "immediate_operand" "I")
3058 (match_operand:SI 2 "immediate_operand" "I"))
3059 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
3060 "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
3061 "<d>ins\t%0,%z3,%2,%1"
3062 [(set_attr "type" "arith")
3063 (set_attr "mode" "<MODE>")])
3064
3065 ;; Unaligned word moves generated by the bit field patterns.
3066 ;;
3067 ;; As far as the rtl is concerned, both the left-part and right-part
3068 ;; instructions can access the whole field. However, the real operand
3069 ;; refers to just the first or the last byte (depending on endianness).
3070 ;; We therefore use two memory operands to each instruction, one to
3071 ;; describe the rtl effect and one to use in the assembly output.
3072 ;;
3073 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3074 ;; This allows us to use the standard length calculations for the "load"
3075 ;; and "store" type attributes.
3076
3077 (define_insn "mov_<load>l"
3078 [(set (match_operand:GPR 0 "register_operand" "=d")
3079 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3080 (match_operand:QI 2 "memory_operand" "m")]
3081 UNSPEC_LOAD_LEFT))]
3082 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3083 "<load>l\t%0,%2"
3084 [(set_attr "type" "load")
3085 (set_attr "mode" "<MODE>")])
3086
3087 (define_insn "mov_<load>r"
3088 [(set (match_operand:GPR 0 "register_operand" "=d")
3089 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3090 (match_operand:QI 2 "memory_operand" "m")
3091 (match_operand:GPR 3 "register_operand" "0")]
3092 UNSPEC_LOAD_RIGHT))]
3093 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
3094 "<load>r\t%0,%2"
3095 [(set_attr "type" "load")
3096 (set_attr "mode" "<MODE>")])
3097
3098 (define_insn "mov_<store>l"
3099 [(set (match_operand:BLK 0 "memory_operand" "=m")
3100 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3101 (match_operand:QI 2 "memory_operand" "m")]
3102 UNSPEC_STORE_LEFT))]
3103 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3104 "<store>l\t%z1,%2"
3105 [(set_attr "type" "store")
3106 (set_attr "mode" "<MODE>")])
3107
3108 (define_insn "mov_<store>r"
3109 [(set (match_operand:BLK 0 "memory_operand" "+m")
3110 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3111 (match_operand:QI 2 "memory_operand" "m")
3112 (match_dup 0)]
3113 UNSPEC_STORE_RIGHT))]
3114 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3115 "<store>r\t%z1,%2"
3116 [(set_attr "type" "store")
3117 (set_attr "mode" "<MODE>")])
3118
3119 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3120 ;; The required value is:
3121 ;;
3122 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3123 ;;
3124 ;; which translates to:
3125 ;;
3126 ;; lui op0,%highest(op1)
3127 ;; daddiu op0,op0,%higher(op1)
3128 ;; dsll op0,op0,16
3129 ;; daddiu op0,op0,%hi(op1)
3130 ;; dsll op0,op0,16
3131 ;;
3132 ;; The split is deferred until after flow2 to allow the peephole2 below
3133 ;; to take effect.
3134 (define_insn_and_split "*lea_high64"
3135 [(set (match_operand:DI 0 "register_operand" "=d")
3136 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3137 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3138 "#"
3139 "&& epilogue_completed"
3140 [(set (match_dup 0) (high:DI (match_dup 2)))
3141 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3142 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3143 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3144 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3145 {
3146 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3147 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3148 }
3149 [(set_attr "length" "20")])
3150
3151 ;; Use a scratch register to reduce the latency of the above pattern
3152 ;; on superscalar machines. The optimized sequence is:
3153 ;;
3154 ;; lui op1,%highest(op2)
3155 ;; lui op0,%hi(op2)
3156 ;; daddiu op1,op1,%higher(op2)
3157 ;; dsll32 op1,op1,0
3158 ;; daddu op1,op1,op0
3159 (define_peephole2
3160 [(set (match_operand:DI 1 "register_operand")
3161 (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3162 (match_scratch:DI 0 "d")]
3163 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3164 [(set (match_dup 1) (high:DI (match_dup 3)))
3165 (set (match_dup 0) (high:DI (match_dup 4)))
3166 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3167 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3168 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3169 {
3170 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3171 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3172 })
3173
3174 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3175 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3176 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3177 ;; used once. We can then use the sequence:
3178 ;;
3179 ;; lui op0,%highest(op1)
3180 ;; lui op2,%hi(op1)
3181 ;; daddiu op0,op0,%higher(op1)
3182 ;; daddiu op2,op2,%lo(op1)
3183 ;; dsll32 op0,op0,0
3184 ;; daddu op0,op0,op2
3185 ;;
3186 ;; which takes 4 cycles on most superscalar targets.
3187 (define_insn_and_split "*lea64"
3188 [(set (match_operand:DI 0 "register_operand" "=d")
3189 (match_operand:DI 1 "general_symbolic_operand" ""))
3190 (clobber (match_scratch:DI 2 "=&d"))]
3191 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3192 "#"
3193 "&& reload_completed"
3194 [(set (match_dup 0) (high:DI (match_dup 3)))
3195 (set (match_dup 2) (high:DI (match_dup 4)))
3196 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3197 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3198 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3199 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3200 {
3201 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3202 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3203 }
3204 [(set_attr "length" "24")])
3205
3206 ;; Insns to fetch a symbol from a big GOT.
3207
3208 (define_insn_and_split "*xgot_hi<mode>"
3209 [(set (match_operand:P 0 "register_operand" "=d")
3210 (high:P (match_operand:P 1 "got_disp_operand" "")))]
3211 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3212 "#"
3213 "&& reload_completed"
3214 [(set (match_dup 0) (high:P (match_dup 2)))
3215 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3216 {
3217 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3218 operands[3] = pic_offset_table_rtx;
3219 }
3220 [(set_attr "got" "xgot_high")
3221 (set_attr "mode" "<MODE>")])
3222
3223 (define_insn_and_split "*xgot_lo<mode>"
3224 [(set (match_operand:P 0 "register_operand" "=d")
3225 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3226 (match_operand:P 2 "got_disp_operand" "")))]
3227 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3228 "#"
3229 "&& reload_completed"
3230 [(set (match_dup 0)
3231 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3232 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
3233 [(set_attr "got" "load")
3234 (set_attr "mode" "<MODE>")])
3235
3236 ;; Insns to fetch a symbol from a normal GOT.
3237
3238 (define_insn_and_split "*got_disp<mode>"
3239 [(set (match_operand:P 0 "register_operand" "=d")
3240 (match_operand:P 1 "got_disp_operand" ""))]
3241 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3242 "#"
3243 "&& reload_completed"
3244 [(set (match_dup 0)
3245 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3246 {
3247 operands[2] = pic_offset_table_rtx;
3248 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
3249 }
3250 [(set_attr "got" "load")
3251 (set_attr "mode" "<MODE>")])
3252
3253 ;; Insns for loading the "page" part of a page/ofst address from the GOT.
3254
3255 (define_insn_and_split "*got_page<mode>"
3256 [(set (match_operand:P 0 "register_operand" "=d")
3257 (high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
3258 "TARGET_EXPLICIT_RELOCS"
3259 "#"
3260 "&& reload_completed"
3261 [(set (match_dup 0)
3262 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3263 {
3264 operands[2] = pic_offset_table_rtx;
3265 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3266 }
3267 [(set_attr "got" "load")
3268 (set_attr "mode" "<MODE>")])
3269
3270 ;; Lower-level instructions for loading an address from the GOT.
3271 ;; We could use MEMs, but an unspec gives more optimization
3272 ;; opportunities.
3273
3274 (define_insn "load_got<mode>"
3275 [(set (match_operand:P 0 "register_operand" "=d")
3276 (unspec:P [(match_operand:P 1 "register_operand" "d")
3277 (match_operand:P 2 "immediate_operand" "")]
3278 UNSPEC_LOAD_GOT))]
3279 ""
3280 "<load>\t%0,%R2(%1)"
3281 [(set_attr "type" "load")
3282 (set_attr "mode" "<MODE>")
3283 (set_attr "length" "4")])
3284
3285 ;; Instructions for adding the low 16 bits of an address to a register.
3286 ;; Operand 2 is the address: print_operand works out which relocation
3287 ;; should be applied.
3288
3289 (define_insn "*low<mode>"
3290 [(set (match_operand:P 0 "register_operand" "=d")
3291 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3292 (match_operand:P 2 "immediate_operand" "")))]
3293 "!TARGET_MIPS16"
3294 "<d>addiu\t%0,%1,%R2"
3295 [(set_attr "type" "arith")
3296 (set_attr "mode" "<MODE>")])
3297
3298 (define_insn "*low<mode>_mips16"
3299 [(set (match_operand:P 0 "register_operand" "=d")
3300 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3301 (match_operand:P 2 "immediate_operand" "")))]
3302 "TARGET_MIPS16"
3303 "<d>addiu\t%0,%R2"
3304 [(set_attr "type" "arith")
3305 (set_attr "mode" "<MODE>")
3306 (set_attr "length" "8")])
3307
3308 ;; Allow combine to split complex const_int load sequences, using operand 2
3309 ;; to store the intermediate results. See move_operand for details.
3310 (define_split
3311 [(set (match_operand:GPR 0 "register_operand")
3312 (match_operand:GPR 1 "splittable_const_int_operand"))
3313 (clobber (match_operand:GPR 2 "register_operand"))]
3314 ""
3315 [(const_int 0)]
3316 {
3317 mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3318 DONE;
3319 })
3320
3321 ;; Likewise, for symbolic operands.
3322 (define_split
3323 [(set (match_operand:P 0 "register_operand")
3324 (match_operand:P 1 "splittable_symbolic_operand"))
3325 (clobber (match_operand:P 2 "register_operand"))]
3326 ""
3327 [(set (match_dup 0) (match_dup 1))]
3328 { operands[1] = mips_split_symbol (operands[2], operands[1]); })
3329
3330 ;; 64-bit integer moves
3331
3332 ;; Unlike most other insns, the move insns can't be split with
3333 ;; different predicates, because register spilling and other parts of
3334 ;; the compiler, have memoized the insn number already.
3335
3336 (define_expand "movdi"
3337 [(set (match_operand:DI 0 "")
3338 (match_operand:DI 1 ""))]
3339 ""
3340 {
3341 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3342 DONE;
3343 })
3344
3345 ;; For mips16, we need a special case to handle storing $31 into
3346 ;; memory, since we don't have a constraint to match $31. This
3347 ;; instruction can be generated by save_restore_insns.
3348
3349 (define_insn "*mov<mode>_ra"
3350 [(set (match_operand:GPR 0 "stack_operand" "=m")
3351 (reg:GPR 31))]
3352 "TARGET_MIPS16"
3353 "<store>\t$31,%0"
3354 [(set_attr "type" "store")
3355 (set_attr "mode" "<MODE>")])
3356
3357 (define_insn "*movdi_32bit"
3358 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3359 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3360 "!TARGET_64BIT && !TARGET_FLOAT64 && !TARGET_MIPS16
3361 && (register_operand (operands[0], DImode)
3362 || reg_or_0_operand (operands[1], DImode))"
3363 { return mips_output_move (operands[0], operands[1]); }
3364 [(set_attr "type" "multi,multi,load,store,mthilo,mfhilo,mtc,load,mfc,store")
3365 (set_attr "mode" "DI")
3366 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3367
3368 (define_insn "*movdi_gp32_fp64"
3369 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*f,*d,*m")
3370 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*f,*J*d,*m,*f,*f"))]
3371 "!TARGET_64BIT && TARGET_FLOAT64 && !TARGET_MIPS16
3372 && (register_operand (operands[0], DImode)
3373 || reg_or_0_operand (operands[1], DImode))"
3374 { return mips_output_move (operands[0], operands[1]); }
3375 [(set_attr "type" "multi,multi,load,store,mthilo,mfhilo,fmove,mtc,fpload,mfc,fpstore")
3376 (set_attr "mode" "DI")
3377 (set_attr "length" "8,16,*,*,8,8,4,8,*,8,*")])
3378
3379 (define_insn "*movdi_32bit_mips16"
3380 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3381 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3382 "!TARGET_64BIT && TARGET_MIPS16
3383 && (register_operand (operands[0], DImode)
3384 || register_operand (operands[1], DImode))"
3385 { return mips_output_move (operands[0], operands[1]); }
3386 [(set_attr "type" "multi,multi,multi,multi,multi,load,store,mfhilo")
3387 (set_attr "mode" "DI")
3388 (set_attr "length" "8,8,8,8,12,*,*,8")])
3389
3390 (define_insn "*movdi_64bit"
3391 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
3392 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
3393 "TARGET_64BIT && !TARGET_MIPS16
3394 && (register_operand (operands[0], DImode)
3395 || reg_or_0_operand (operands[1], DImode))"
3396 { return mips_output_move (operands[0], operands[1]); }
3397 [(set_attr "type" "move,const,const,load,store,fmove,mtc,fpload,mfc,fpstore,mthilo,mtc,load,mfc,store")
3398 (set_attr "mode" "DI")
3399 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3400
3401 (define_insn "*movdi_64bit_mips16"
3402 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3403 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3404 "TARGET_64BIT && TARGET_MIPS16
3405 && (register_operand (operands[0], DImode)
3406 || register_operand (operands[1], DImode))"
3407 { return mips_output_move (operands[0], operands[1]); }
3408 [(set_attr "type" "move,move,move,arith,arith,const,load,store")
3409 (set_attr "mode" "DI")
3410 (set_attr_alternative "length"
3411 [(const_int 4)
3412 (const_int 4)
3413 (const_int 4)
3414 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3415 (const_int 4)
3416 (const_int 8))
3417 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3418 (const_int 8)
3419 (const_int 12))
3420 (const_string "*")
3421 (const_string "*")
3422 (const_string "*")])])
3423
3424
3425 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3426 ;; when the original load is a 4 byte instruction but the add and the
3427 ;; load are 2 2 byte instructions.
3428
3429 (define_split
3430 [(set (match_operand:DI 0 "register_operand")
3431 (mem:DI (plus:DI (match_dup 0)
3432 (match_operand:DI 1 "const_int_operand"))))]
3433 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3434 && !TARGET_DEBUG_D_MODE
3435 && REG_P (operands[0])
3436 && M16_REG_P (REGNO (operands[0]))
3437 && GET_CODE (operands[1]) == CONST_INT
3438 && ((INTVAL (operands[1]) < 0
3439 && INTVAL (operands[1]) >= -0x10)
3440 || (INTVAL (operands[1]) >= 32 * 8
3441 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3442 || (INTVAL (operands[1]) >= 0
3443 && INTVAL (operands[1]) < 32 * 8
3444 && (INTVAL (operands[1]) & 7) != 0))"
3445 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3446 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3447 {
3448 HOST_WIDE_INT val = INTVAL (operands[1]);
3449
3450 if (val < 0)
3451 operands[2] = const0_rtx;
3452 else if (val >= 32 * 8)
3453 {
3454 int off = val & 7;
3455
3456 operands[1] = GEN_INT (0x8 + off);
3457 operands[2] = GEN_INT (val - off - 0x8);
3458 }
3459 else
3460 {
3461 int off = val & 7;
3462
3463 operands[1] = GEN_INT (off);
3464 operands[2] = GEN_INT (val - off);
3465 }
3466 })
3467
3468 ;; 32-bit Integer moves
3469
3470 ;; Unlike most other insns, the move insns can't be split with
3471 ;; different predicates, because register spilling and other parts of
3472 ;; the compiler, have memoized the insn number already.
3473
3474 (define_expand "movsi"
3475 [(set (match_operand:SI 0 "")
3476 (match_operand:SI 1 ""))]
3477 ""
3478 {
3479 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3480 DONE;
3481 })
3482
3483 ;; The difference between these two is whether or not ints are allowed
3484 ;; in FP registers (off by default, use -mdebugh to enable).
3485
3486 (define_insn "*movsi_internal"
3487 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
3488 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))]
3489 "!TARGET_MIPS16
3490 && (register_operand (operands[0], SImode)
3491 || reg_or_0_operand (operands[1], SImode))"
3492 { return mips_output_move (operands[0], operands[1]); }
3493 [(set_attr "type" "move,const,const,load,store,fmove,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,load,mfc,store")
3494 (set_attr "mode" "SI")
3495 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3496
3497 (define_insn "*movsi_mips16"
3498 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3499 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3500 "TARGET_MIPS16
3501 && (register_operand (operands[0], SImode)
3502 || register_operand (operands[1], SImode))"
3503 { return mips_output_move (operands[0], operands[1]); }
3504 [(set_attr "type" "move,move,move,arith,arith,const,load,store")
3505 (set_attr "mode" "SI")
3506 (set_attr_alternative "length"
3507 [(const_int 4)
3508 (const_int 4)
3509 (const_int 4)
3510 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3511 (const_int 4)
3512 (const_int 8))
3513 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3514 (const_int 8)
3515 (const_int 12))
3516 (const_string "*")
3517 (const_string "*")
3518 (const_string "*")])])
3519
3520 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
3521 ;; when the original load is a 4 byte instruction but the add and the
3522 ;; load are 2 2 byte instructions.
3523
3524 (define_split
3525 [(set (match_operand:SI 0 "register_operand")
3526 (mem:SI (plus:SI (match_dup 0)
3527 (match_operand:SI 1 "const_int_operand"))))]
3528 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3529 && REG_P (operands[0])
3530 && M16_REG_P (REGNO (operands[0]))
3531 && GET_CODE (operands[1]) == CONST_INT
3532 && ((INTVAL (operands[1]) < 0
3533 && INTVAL (operands[1]) >= -0x80)
3534 || (INTVAL (operands[1]) >= 32 * 4
3535 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3536 || (INTVAL (operands[1]) >= 0
3537 && INTVAL (operands[1]) < 32 * 4
3538 && (INTVAL (operands[1]) & 3) != 0))"
3539 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3540 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3541 {
3542 HOST_WIDE_INT val = INTVAL (operands[1]);
3543
3544 if (val < 0)
3545 operands[2] = const0_rtx;
3546 else if (val >= 32 * 4)
3547 {
3548 int off = val & 3;
3549
3550 operands[1] = GEN_INT (0x7c + off);
3551 operands[2] = GEN_INT (val - off - 0x7c);
3552 }
3553 else
3554 {
3555 int off = val & 3;
3556
3557 operands[1] = GEN_INT (off);
3558 operands[2] = GEN_INT (val - off);
3559 }
3560 })
3561
3562 ;; On the mips16, we can split a load of certain constants into a load
3563 ;; and an add. This turns a 4 byte instruction into 2 2 byte
3564 ;; instructions.
3565
3566 (define_split
3567 [(set (match_operand:SI 0 "register_operand")
3568 (match_operand:SI 1 "const_int_operand"))]
3569 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3570 && REG_P (operands[0])
3571 && M16_REG_P (REGNO (operands[0]))
3572 && GET_CODE (operands[1]) == CONST_INT
3573 && INTVAL (operands[1]) >= 0x100
3574 && INTVAL (operands[1]) <= 0xff + 0x7f"
3575 [(set (match_dup 0) (match_dup 1))
3576 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3577 {
3578 int val = INTVAL (operands[1]);
3579
3580 operands[1] = GEN_INT (0xff);
3581 operands[2] = GEN_INT (val - 0xff);
3582 })
3583
3584 ;; This insn handles moving CCmode values. It's really just a
3585 ;; slightly simplified copy of movsi_internal2, with additional cases
3586 ;; to move a condition register to a general register and to move
3587 ;; between the general registers and the floating point registers.
3588
3589 (define_insn "movcc"
3590 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3591 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3592 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3593 { return mips_output_move (operands[0], operands[1]); }
3594 [(set_attr "type" "multi,move,load,store,mfc,mtc,fmove,fpload,fpstore")
3595 (set_attr "mode" "SI")
3596 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3597
3598 ;; Reload condition code registers. reload_incc and reload_outcc
3599 ;; both handle moves from arbitrary operands into condition code
3600 ;; registers. reload_incc handles the more common case in which
3601 ;; a source operand is constrained to be in a condition-code
3602 ;; register, but has not been allocated to one.
3603 ;;
3604 ;; Sometimes, such as in movcc, we have a CCmode destination whose
3605 ;; constraints do not include 'z'. reload_outcc handles the case
3606 ;; when such an operand is allocated to a condition-code register.
3607 ;;
3608 ;; Note that reloads from a condition code register to some
3609 ;; other location can be done using ordinary moves. Moving
3610 ;; into a GPR takes a single movcc, moving elsewhere takes
3611 ;; two. We can leave these cases to the generic reload code.
3612 (define_expand "reload_incc"
3613 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3614 (match_operand:CC 1 "general_operand" ""))
3615 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3616 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3617 {
3618 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3619 DONE;
3620 })
3621
3622 (define_expand "reload_outcc"
3623 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3624 (match_operand:CC 1 "register_operand" ""))
3625 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3626 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3627 {
3628 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3629 DONE;
3630 })
3631
3632 ;; MIPS4 supports loading and storing a floating point register from
3633 ;; the sum of two general registers. We use two versions for each of
3634 ;; these four instructions: one where the two general registers are
3635 ;; SImode, and one where they are DImode. This is because general
3636 ;; registers will be in SImode when they hold 32-bit values, but,
3637 ;; since the 32-bit values are always sign extended, the [ls][wd]xc1
3638 ;; instructions will still work correctly.
3639
3640 ;; ??? Perhaps it would be better to support these instructions by
3641 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3642 ;; these instructions can only be used to load and store floating
3643 ;; point registers, that would probably cause trouble in reload.
3644
3645 (define_insn "*<ANYF:loadx>_<P:mode>"
3646 [(set (match_operand:ANYF 0 "register_operand" "=f")
3647 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3648 (match_operand:P 2 "register_operand" "d"))))]
3649 "ISA_HAS_FP4"
3650 "<ANYF:loadx>\t%0,%1(%2)"
3651 [(set_attr "type" "fpidxload")
3652 (set_attr "mode" "<ANYF:UNITMODE>")])
3653
3654 (define_insn "*<ANYF:storex>_<P:mode>"
3655 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3656 (match_operand:P 2 "register_operand" "d")))
3657 (match_operand:ANYF 0 "register_operand" "f"))]
3658 "ISA_HAS_FP4"
3659 "<ANYF:storex>\t%0,%1(%2)"
3660 [(set_attr "type" "fpidxstore")
3661 (set_attr "mode" "<ANYF:UNITMODE>")])
3662
3663 ;; Scaled indexed address load.
3664 ;; Per md.texi, we only need to look for a pattern with multiply in the
3665 ;; address expression, not shift.
3666
3667 (define_insn "*lwxs"
3668 [(set (match_operand:SI 0 "register_operand" "=d")
3669 (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
3670 (const_int 4))
3671 (match_operand:SI 2 "register_operand" "d"))))]
3672 "ISA_HAS_LWXS"
3673 "lwxs\t%0,%1(%2)"
3674 [(set_attr "type" "load")
3675 (set_attr "mode" "SI")
3676 (set_attr "length" "4")])
3677
3678 ;; 16-bit Integer moves
3679
3680 ;; Unlike most other insns, the move insns can't be split with
3681 ;; different predicates, because register spilling and other parts of
3682 ;; the compiler, have memoized the insn number already.
3683 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3684
3685 (define_expand "movhi"
3686 [(set (match_operand:HI 0 "")
3687 (match_operand:HI 1 ""))]
3688 ""
3689 {
3690 if (mips_legitimize_move (HImode, operands[0], operands[1]))
3691 DONE;
3692 })
3693
3694 (define_insn "*movhi_internal"
3695 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3696 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3697 "!TARGET_MIPS16
3698 && (register_operand (operands[0], HImode)
3699 || reg_or_0_operand (operands[1], HImode))"
3700 "@
3701 move\t%0,%1
3702 li\t%0,%1
3703 lhu\t%0,%1
3704 sh\t%z1,%0
3705 mfc1\t%0,%1
3706 mtc1\t%1,%0
3707 mov.s\t%0,%1
3708 mt%0\t%1"
3709 [(set_attr "type" "move,arith,load,store,mfc,mtc,fmove,mthilo")
3710 (set_attr "mode" "HI")
3711 (set_attr "length" "4,4,*,*,4,4,4,4")])
3712
3713 (define_insn "*movhi_mips16"
3714 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3715 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
3716 "TARGET_MIPS16
3717 && (register_operand (operands[0], HImode)
3718 || register_operand (operands[1], HImode))"
3719 "@
3720 move\t%0,%1
3721 move\t%0,%1
3722 move\t%0,%1
3723 li\t%0,%1
3724 #
3725 lhu\t%0,%1
3726 sh\t%1,%0"
3727 [(set_attr "type" "move,move,move,arith,arith,load,store")
3728 (set_attr "mode" "HI")
3729 (set_attr_alternative "length"
3730 [(const_int 4)
3731 (const_int 4)
3732 (const_int 4)
3733 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3734 (const_int 4)
3735 (const_int 8))
3736 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3737 (const_int 8)
3738 (const_int 12))
3739 (const_string "*")
3740 (const_string "*")])])
3741
3742
3743 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
3744 ;; when the original load is a 4 byte instruction but the add and the
3745 ;; load are 2 2 byte instructions.
3746
3747 (define_split
3748 [(set (match_operand:HI 0 "register_operand")
3749 (mem:HI (plus:SI (match_dup 0)
3750 (match_operand:SI 1 "const_int_operand"))))]
3751 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3752 && REG_P (operands[0])
3753 && M16_REG_P (REGNO (operands[0]))
3754 && GET_CODE (operands[1]) == CONST_INT
3755 && ((INTVAL (operands[1]) < 0
3756 && INTVAL (operands[1]) >= -0x80)
3757 || (INTVAL (operands[1]) >= 32 * 2
3758 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3759 || (INTVAL (operands[1]) >= 0
3760 && INTVAL (operands[1]) < 32 * 2
3761 && (INTVAL (operands[1]) & 1) != 0))"
3762 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3763 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3764 {
3765 HOST_WIDE_INT val = INTVAL (operands[1]);
3766
3767 if (val < 0)
3768 operands[2] = const0_rtx;
3769 else if (val >= 32 * 2)
3770 {
3771 int off = val & 1;
3772
3773 operands[1] = GEN_INT (0x7e + off);
3774 operands[2] = GEN_INT (val - off - 0x7e);
3775 }
3776 else
3777 {
3778 int off = val & 1;
3779
3780 operands[1] = GEN_INT (off);
3781 operands[2] = GEN_INT (val - off);
3782 }
3783 })
3784
3785 ;; 8-bit Integer moves
3786
3787 ;; Unlike most other insns, the move insns can't be split with
3788 ;; different predicates, because register spilling and other parts of
3789 ;; the compiler, have memoized the insn number already.
3790 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3791
3792 (define_expand "movqi"
3793 [(set (match_operand:QI 0 "")
3794 (match_operand:QI 1 ""))]
3795 ""
3796 {
3797 if (mips_legitimize_move (QImode, operands[0], operands[1]))
3798 DONE;
3799 })
3800
3801 (define_insn "*movqi_internal"
3802 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3803 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3804 "!TARGET_MIPS16
3805 && (register_operand (operands[0], QImode)
3806 || reg_or_0_operand (operands[1], QImode))"
3807 "@
3808 move\t%0,%1
3809 li\t%0,%1
3810 lbu\t%0,%1
3811 sb\t%z1,%0
3812 mfc1\t%0,%1
3813 mtc1\t%1,%0
3814 mov.s\t%0,%1
3815 mt%0\t%1"
3816 [(set_attr "type" "move,arith,load,store,mfc,mtc,fmove,mthilo")
3817 (set_attr "mode" "QI")
3818 (set_attr "length" "4,4,*,*,4,4,4,4")])
3819
3820 (define_insn "*movqi_mips16"
3821 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3822 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
3823 "TARGET_MIPS16
3824 && (register_operand (operands[0], QImode)
3825 || register_operand (operands[1], QImode))"
3826 "@
3827 move\t%0,%1
3828 move\t%0,%1
3829 move\t%0,%1
3830 li\t%0,%1
3831 #
3832 lbu\t%0,%1
3833 sb\t%1,%0"
3834 [(set_attr "type" "move,move,move,arith,arith,load,store")
3835 (set_attr "mode" "QI")
3836 (set_attr "length" "4,4,4,4,8,*,*")])
3837
3838 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
3839 ;; when the original load is a 4 byte instruction but the add and the
3840 ;; load are 2 2 byte instructions.
3841
3842 (define_split
3843 [(set (match_operand:QI 0 "register_operand")
3844 (mem:QI (plus:SI (match_dup 0)
3845 (match_operand:SI 1 "const_int_operand"))))]
3846 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3847 && REG_P (operands[0])
3848 && M16_REG_P (REGNO (operands[0]))
3849 && GET_CODE (operands[1]) == CONST_INT
3850 && ((INTVAL (operands[1]) < 0
3851 && INTVAL (operands[1]) >= -0x80)
3852 || (INTVAL (operands[1]) >= 32
3853 && INTVAL (operands[1]) <= 31 + 0x7f))"
3854 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3855 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3856 {
3857 HOST_WIDE_INT val = INTVAL (operands[1]);
3858
3859 if (val < 0)
3860 operands[2] = const0_rtx;
3861 else
3862 {
3863 operands[1] = GEN_INT (0x7f);
3864 operands[2] = GEN_INT (val - 0x7f);
3865 }
3866 })
3867
3868 ;; 32-bit floating point moves
3869
3870 (define_expand "movsf"
3871 [(set (match_operand:SF 0 "")
3872 (match_operand:SF 1 ""))]
3873 ""
3874 {
3875 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3876 DONE;
3877 })
3878
3879 (define_insn "*movsf_hardfloat"
3880 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3881 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3882 "TARGET_HARD_FLOAT
3883 && (register_operand (operands[0], SFmode)
3884 || reg_or_0_operand (operands[1], SFmode))"
3885 { return mips_output_move (operands[0], operands[1]); }
3886 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3887 (set_attr "mode" "SF")
3888 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3889
3890 (define_insn "*movsf_softfloat"
3891 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3892 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3893 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3894 && (register_operand (operands[0], SFmode)
3895 || reg_or_0_operand (operands[1], SFmode))"
3896 { return mips_output_move (operands[0], operands[1]); }
3897 [(set_attr "type" "move,load,store")
3898 (set_attr "mode" "SF")
3899 (set_attr "length" "4,*,*")])
3900
3901 (define_insn "*movsf_mips16"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3903 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3904 "TARGET_MIPS16
3905 && (register_operand (operands[0], SFmode)
3906 || register_operand (operands[1], SFmode))"
3907 { return mips_output_move (operands[0], operands[1]); }
3908 [(set_attr "type" "move,move,move,load,store")
3909 (set_attr "mode" "SF")
3910 (set_attr "length" "4,4,4,*,*")])
3911
3912
3913 ;; 64-bit floating point moves
3914
3915 (define_expand "movdf"
3916 [(set (match_operand:DF 0 "")
3917 (match_operand:DF 1 ""))]
3918 ""
3919 {
3920 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3921 DONE;
3922 })
3923
3924 (define_insn "*movdf_hardfloat_64bit"
3925 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3926 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3927 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3928 && (register_operand (operands[0], DFmode)
3929 || reg_or_0_operand (operands[1], DFmode))"
3930 { return mips_output_move (operands[0], operands[1]); }
3931 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3932 (set_attr "mode" "DF")
3933 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3934
3935 ;; This pattern applies to both !TARGET_FLOAT64 and TARGET_FLOAT64.
3936 (define_insn "*movdf_hardfloat_32bit"
3937 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3938 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3939 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3940 && (register_operand (operands[0], DFmode)
3941 || reg_or_0_operand (operands[1], DFmode))"
3942 { return mips_output_move (operands[0], operands[1]); }
3943 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
3944 (set_attr "mode" "DF")
3945 (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
3946
3947 (define_insn "*movdf_softfloat"
3948 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3949 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3950 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3951 && (register_operand (operands[0], DFmode)
3952 || reg_or_0_operand (operands[1], DFmode))"
3953 { return mips_output_move (operands[0], operands[1]); }
3954 [(set_attr "type" "multi,load,store,mfc,mtc,fmove")
3955 (set_attr "mode" "DF")
3956 (set_attr "length" "8,*,*,4,4,4")])
3957
3958 (define_insn "*movdf_mips16"
3959 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3960 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3961 "TARGET_MIPS16
3962 && (register_operand (operands[0], DFmode)
3963 || register_operand (operands[1], DFmode))"
3964 { return mips_output_move (operands[0], operands[1]); }
3965 [(set_attr "type" "multi,multi,multi,load,store")
3966 (set_attr "mode" "DF")
3967 (set_attr "length" "8,8,8,*,*")])
3968
3969 (define_split
3970 [(set (match_operand:DI 0 "nonimmediate_operand")
3971 (match_operand:DI 1 "move_operand"))]
3972 "reload_completed && !TARGET_64BIT
3973 && mips_split_64bit_move_p (operands[0], operands[1])"
3974 [(const_int 0)]
3975 {
3976 mips_split_64bit_move (operands[0], operands[1]);
3977 DONE;
3978 })
3979
3980 (define_split
3981 [(set (match_operand:DF 0 "nonimmediate_operand")
3982 (match_operand:DF 1 "move_operand"))]
3983 "reload_completed && !TARGET_64BIT
3984 && mips_split_64bit_move_p (operands[0], operands[1])"
3985 [(const_int 0)]
3986 {
3987 mips_split_64bit_move (operands[0], operands[1]);
3988 DONE;
3989 })
3990
3991 ;; When generating mips16 code, split moves of negative constants into
3992 ;; a positive "li" followed by a negation.
3993 (define_split
3994 [(set (match_operand 0 "register_operand")
3995 (match_operand 1 "const_int_operand"))]
3996 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3997 [(set (match_dup 2)
3998 (match_dup 3))
3999 (set (match_dup 2)
4000 (neg:SI (match_dup 2)))]
4001 {
4002 operands[2] = gen_lowpart (SImode, operands[0]);
4003 operands[3] = GEN_INT (-INTVAL (operands[1]));
4004 })
4005
4006 ;; 64-bit paired-single floating point moves
4007
4008 (define_expand "movv2sf"
4009 [(set (match_operand:V2SF 0)
4010 (match_operand:V2SF 1))]
4011 "TARGET_PAIRED_SINGLE_FLOAT"
4012 {
4013 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
4014 DONE;
4015 })
4016
4017 (define_insn "movv2sf_hardfloat_64bit"
4018 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
4019 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
4020 "TARGET_PAIRED_SINGLE_FLOAT
4021 && TARGET_64BIT
4022 && (register_operand (operands[0], V2SFmode)
4023 || reg_or_0_operand (operands[1], V2SFmode))"
4024 { return mips_output_move (operands[0], operands[1]); }
4025 [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
4026 (set_attr "mode" "SF")
4027 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
4028
4029 ;; The HI and LO registers are not truly independent. If we move an mthi
4030 ;; instruction before an mflo instruction, it will make the result of the
4031 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4032 ;;
4033 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4034 ;; Operand 1 is the register we want, operand 2 is the other one.
4035 ;;
4036 ;; When generating VR4120 or VR4130 code, we use macc{,hi} and
4037 ;; dmacc{,hi} instead of mfhi and mflo. This avoids both the normal
4038 ;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
4039
4040 (define_expand "mfhilo_<mode>"
4041 [(set (match_operand:GPR 0 "register_operand")
4042 (unspec:GPR [(match_operand:GPR 1 "register_operand")
4043 (match_operand:GPR 2 "register_operand")]
4044 UNSPEC_MFHILO))])
4045
4046 (define_insn "*mfhilo_<mode>"
4047 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4048 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4049 (match_operand:GPR 2 "register_operand" "l,h")]
4050 UNSPEC_MFHILO))]
4051 "!ISA_HAS_MACCHI"
4052 "mf%1\t%0"
4053 [(set_attr "type" "mfhilo")
4054 (set_attr "mode" "<MODE>")])
4055
4056 (define_insn "*mfhilo_<mode>_macc"
4057 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4058 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
4059 (match_operand:GPR 2 "register_operand" "l,h")]
4060 UNSPEC_MFHILO))]
4061 "ISA_HAS_MACCHI"
4062 {
4063 if (REGNO (operands[1]) == HI_REGNUM)
4064 return "<d>macchi\t%0,%.,%.";
4065 else
4066 return "<d>macc\t%0,%.,%.";
4067 }
4068 [(set_attr "type" "mfhilo")
4069 (set_attr "mode" "<MODE>")])
4070
4071 ;; Patterns for loading or storing part of a paired floating point
4072 ;; register. We need them because odd-numbered floating-point registers
4073 ;; are not fully independent: see mips_split_64bit_move.
4074
4075 ;; Load the low word of operand 0 with operand 1.
4076 (define_insn "load_df_low"
4077 [(set (match_operand:DF 0 "register_operand" "=f,f")
4078 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4079 UNSPEC_LOAD_DF_LOW))]
4080 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4081 {
4082 operands[0] = mips_subword (operands[0], 0);
4083 return mips_output_move (operands[0], operands[1]);
4084 }
4085 [(set_attr "type" "mtc,fpload")
4086 (set_attr "mode" "SF")])
4087
4088 ;; Load the high word of operand 0 from operand 1, preserving the value
4089 ;; in the low word.
4090 (define_insn "load_df_high"
4091 [(set (match_operand:DF 0 "register_operand" "=f,f")
4092 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4093 (match_operand:DF 2 "register_operand" "0,0")]
4094 UNSPEC_LOAD_DF_HIGH))]
4095 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4096 {
4097 operands[0] = mips_subword (operands[0], 1);
4098 return mips_output_move (operands[0], operands[1]);
4099 }
4100 [(set_attr "type" "mtc,fpload")
4101 (set_attr "mode" "SF")])
4102
4103 ;; Store the high word of operand 1 in operand 0. The corresponding
4104 ;; low-word move is done in the normal way.
4105 (define_insn "store_df_high"
4106 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4107 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4108 UNSPEC_STORE_DF_HIGH))]
4109 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4110 {
4111 operands[1] = mips_subword (operands[1], 1);
4112 return mips_output_move (operands[0], operands[1]);
4113 }
4114 [(set_attr "type" "mfc,fpstore")
4115 (set_attr "mode" "SF")])
4116
4117 ;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
4118 ;; value in the low word.
4119 (define_insn "mthc1"
4120 [(set (match_operand:DF 0 "register_operand" "=f")
4121 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ")
4122 (match_operand:DF 2 "register_operand" "0")]
4123 UNSPEC_MTHC1))]
4124 "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
4125 "mthc1\t%z1,%0"
4126 [(set_attr "type" "mtc")
4127 (set_attr "mode" "SF")])
4128
4129 ;; Move high word of operand 1 to operand 0 using mfhc1. The corresponding
4130 ;; low-word move is done in the normal way.
4131 (define_insn "mfhc1"
4132 [(set (match_operand:SI 0 "register_operand" "=d")
4133 (unspec:SI [(match_operand:DF 1 "register_operand" "f")]
4134 UNSPEC_MFHC1))]
4135 "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
4136 "mfhc1\t%0,%1"
4137 [(set_attr "type" "mfc")
4138 (set_attr "mode" "SF")])
4139
4140 ;; Move a constant that satisfies CONST_GP_P into operand 0.
4141 (define_expand "load_const_gp"
4142 [(set (match_operand 0 "register_operand" "=d")
4143 (const (unspec [(const_int 0)] UNSPEC_GP)))])
4144
4145 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4146 ;; of _gp from the start of this function. Operand 1 is the incoming
4147 ;; function address.
4148 (define_insn_and_split "loadgp_newabi"
4149 [(unspec_volatile [(match_operand 0 "" "")
4150 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4151 "mips_current_loadgp_style () == LOADGP_NEWABI"
4152 "#"
4153 ""
4154 [(set (match_dup 2) (match_dup 3))
4155 (set (match_dup 2) (match_dup 4))
4156 (set (match_dup 2) (match_dup 5))]
4157 {
4158 operands[2] = pic_offset_table_rtx;
4159 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4160 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4161 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4162 }
4163 [(set_attr "length" "12")])
4164
4165 ;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
4166 (define_insn_and_split "loadgp_absolute"
4167 [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4168 "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4169 "#"
4170 ""
4171 [(const_int 0)]
4172 {
4173 emit_move_insn (pic_offset_table_rtx, operands[0]);
4174 DONE;
4175 }
4176 [(set_attr "length" "8")])
4177
4178 ;; The use of gp is hidden when not using explicit relocations.
4179 ;; This blockage instruction prevents the gp load from being
4180 ;; scheduled after an implicit use of gp. It also prevents
4181 ;; the load from being deleted as dead.
4182 (define_insn "loadgp_blockage"
4183 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4184 ""
4185 ""
4186 [(set_attr "type" "unknown")
4187 (set_attr "mode" "none")
4188 (set_attr "length" "0")])
4189
4190 ;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol
4191 ;; and operand 1 is the __GOTT_INDEX__ symbol.
4192 (define_insn "loadgp_rtp"
4193 [(unspec_volatile [(match_operand 0 "symbol_ref_operand")
4194 (match_operand 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
4195 "mips_current_loadgp_style () == LOADGP_RTP"
4196 "#"
4197 [(set_attr "length" "12")])
4198
4199 (define_split
4200 [(unspec_volatile [(match_operand:P 0 "symbol_ref_operand")
4201 (match_operand:P 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
4202 "mips_current_loadgp_style () == LOADGP_RTP"
4203 [(set (match_dup 2) (high:P (match_dup 3)))
4204 (set (match_dup 2) (unspec:P [(match_dup 2)
4205 (match_dup 3)] UNSPEC_LOAD_GOT))
4206 (set (match_dup 2) (unspec:P [(match_dup 2)
4207 (match_dup 4)] UNSPEC_LOAD_GOT))]
4208 {
4209 operands[2] = pic_offset_table_rtx;
4210 operands[3] = mips_unspec_address (operands[0], SYMBOL_GENERAL);
4211 operands[4] = mips_unspec_address (operands[1], SYMBOL_HALF);
4212 })
4213
4214 ;; Emit a .cprestore directive, which normally expands to a single store
4215 ;; instruction. Note that we continue to use .cprestore for explicit reloc
4216 ;; code so that jals inside inline asms will work correctly.
4217 (define_insn "cprestore"
4218 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")
4219 (use (reg:SI 28))]
4220 UNSPEC_CPRESTORE)]
4221 ""
4222 {
4223 if (set_nomacro && which_alternative == 1)
4224 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4225 else
4226 return ".cprestore\t%0";
4227 }
4228 [(set_attr "type" "store")
4229 (set_attr "length" "4,12")])
4230
4231 ;; Expand in-line code to clear the instruction cache between operand[0] and
4232 ;; operand[1].
4233 (define_expand "clear_cache"
4234 [(match_operand 0 "pmode_register_operand")
4235 (match_operand 1 "pmode_register_operand")]
4236 ""
4237 "
4238 {
4239 if (ISA_HAS_SYNCI)
4240 {
4241 mips_expand_synci_loop (operands[0], operands[1]);
4242 emit_insn (gen_sync ());
4243 emit_insn (gen_clear_hazard ());
4244 }
4245 else if (mips_cache_flush_func && mips_cache_flush_func[0])
4246 {
4247 rtx len = gen_reg_rtx (Pmode);
4248 emit_insn (gen_sub3_insn (len, operands[1], operands[0]));
4249 /* Flush both caches. We need to flush the data cache in case
4250 the system has a write-back cache. */
4251 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func),
4252 0, VOIDmode, 3, operands[0], Pmode,
4253 len, TYPE_MODE (integer_type_node),
4254 GEN_INT (3), TYPE_MODE (integer_type_node));
4255 }
4256 DONE;
4257 }")
4258
4259 (define_insn "sync"
4260 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
4261 "ISA_HAS_SYNCI"
4262 "sync")
4263
4264 (define_insn "synci"
4265 [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
4266 UNSPEC_SYNCI)]
4267 "ISA_HAS_SYNCI"
4268 "synci\t0(%0)")
4269
4270 (define_insn "rdhwr"
4271 [(set (match_operand:SI 0 "general_operand" "=d")
4272 (unspec_volatile [(match_operand:SI 1 "const_int_operand" "n")]
4273 UNSPEC_RDHWR))]
4274 "ISA_HAS_SYNCI"
4275 "rdhwr\t%0,$%1")
4276
4277 (define_insn "clear_hazard"
4278 [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
4279 (clobber (reg:SI 31))]
4280 "ISA_HAS_SYNCI"
4281 {
4282 return ".set\tpush\n"
4283 "\t.set\tnoreorder\n"
4284 "\t.set\tnomacro\n"
4285 "\tbal\t1f\n"
4286 "\tnop\n"
4287 "1:\taddiu\t$31,$31,12\n"
4288 "\tjr.hb\t$31\n"
4289 "\tnop\n"
4290 "\t.set\tpop";
4291 }
4292 [(set_attr "length" "20")])
4293 \f
4294 ;; Block moves, see mips.c for more details.
4295 ;; Argument 0 is the destination
4296 ;; Argument 1 is the source
4297 ;; Argument 2 is the length
4298 ;; Argument 3 is the alignment
4299
4300 (define_expand "movmemsi"
4301 [(parallel [(set (match_operand:BLK 0 "general_operand")
4302 (match_operand:BLK 1 "general_operand"))
4303 (use (match_operand:SI 2 ""))
4304 (use (match_operand:SI 3 "const_int_operand"))])]
4305 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4306 {
4307 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4308 DONE;
4309 else
4310 FAIL;
4311 })
4312 \f
4313 ;;
4314 ;; ....................
4315 ;;
4316 ;; SHIFTS
4317 ;;
4318 ;; ....................
4319
4320 (define_expand "<optab><mode>3"
4321 [(set (match_operand:GPR 0 "register_operand")
4322 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4323 (match_operand:SI 2 "arith_operand")))]
4324 ""
4325 {
4326 /* On the mips16, a shift of more than 8 is a four byte instruction,
4327 so, for a shift between 8 and 16, it is just as fast to do two
4328 shifts of 8 or less. If there is a lot of shifting going on, we
4329 may win in CSE. Otherwise combine will put the shifts back
4330 together again. This can be called by function_arg, so we must
4331 be careful not to allocate a new register if we've reached the
4332 reload pass. */
4333 if (TARGET_MIPS16
4334 && optimize
4335 && GET_CODE (operands[2]) == CONST_INT
4336 && INTVAL (operands[2]) > 8
4337 && INTVAL (operands[2]) <= 16
4338 && !reload_in_progress
4339 && !reload_completed)
4340 {
4341 rtx temp = gen_reg_rtx (<MODE>mode);
4342
4343 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4344 emit_insn (gen_<optab><mode>3 (operands[0], temp,
4345 GEN_INT (INTVAL (operands[2]) - 8)));
4346 DONE;
4347 }
4348 })
4349
4350 (define_insn "*<optab><mode>3"
4351 [(set (match_operand:GPR 0 "register_operand" "=d")
4352 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4353 (match_operand:SI 2 "arith_operand" "dI")))]
4354 "!TARGET_MIPS16"
4355 {
4356 if (GET_CODE (operands[2]) == CONST_INT)
4357 operands[2] = GEN_INT (INTVAL (operands[2])
4358 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4359
4360 return "<d><insn>\t%0,%1,%2";
4361 }
4362 [(set_attr "type" "shift")
4363 (set_attr "mode" "<MODE>")])
4364
4365 (define_insn "*<optab>si3_extend"
4366 [(set (match_operand:DI 0 "register_operand" "=d")
4367 (sign_extend:DI
4368 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4369 (match_operand:SI 2 "arith_operand" "dI"))))]
4370 "TARGET_64BIT && !TARGET_MIPS16"
4371 {
4372 if (GET_CODE (operands[2]) == CONST_INT)
4373 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4374
4375 return "<insn>\t%0,%1,%2";
4376 }
4377 [(set_attr "type" "shift")
4378 (set_attr "mode" "SI")])
4379
4380 (define_insn "*<optab>si3_mips16"
4381 [(set (match_operand:SI 0 "register_operand" "=d,d")
4382 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4383 (match_operand:SI 2 "arith_operand" "d,I")))]
4384 "TARGET_MIPS16"
4385 {
4386 if (which_alternative == 0)
4387 return "<insn>\t%0,%2";
4388
4389 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4390 return "<insn>\t%0,%1,%2";
4391 }
4392 [(set_attr "type" "shift")
4393 (set_attr "mode" "SI")
4394 (set_attr_alternative "length"
4395 [(const_int 4)
4396 (if_then_else (match_operand 2 "m16_uimm3_b")
4397 (const_int 4)
4398 (const_int 8))])])
4399
4400 ;; We need separate DImode MIPS16 patterns because of the irregularity
4401 ;; of right shifts.
4402 (define_insn "*ashldi3_mips16"
4403 [(set (match_operand:DI 0 "register_operand" "=d,d")
4404 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4405 (match_operand:SI 2 "arith_operand" "d,I")))]
4406 "TARGET_64BIT && TARGET_MIPS16"
4407 {
4408 if (which_alternative == 0)
4409 return "dsll\t%0,%2";
4410
4411 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4412 return "dsll\t%0,%1,%2";
4413 }
4414 [(set_attr "type" "shift")
4415 (set_attr "mode" "DI")
4416 (set_attr_alternative "length"
4417 [(const_int 4)
4418 (if_then_else (match_operand 2 "m16_uimm3_b")
4419 (const_int 4)
4420 (const_int 8))])])
4421
4422 (define_insn "*ashrdi3_mips16"
4423 [(set (match_operand:DI 0 "register_operand" "=d,d")
4424 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4425 (match_operand:SI 2 "arith_operand" "d,I")))]
4426 "TARGET_64BIT && TARGET_MIPS16"
4427 {
4428 if (GET_CODE (operands[2]) == CONST_INT)
4429 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4430
4431 return "dsra\t%0,%2";
4432 }
4433 [(set_attr "type" "shift")
4434 (set_attr "mode" "DI")
4435 (set_attr_alternative "length"
4436 [(const_int 4)
4437 (if_then_else (match_operand 2 "m16_uimm3_b")
4438 (const_int 4)
4439 (const_int 8))])])
4440
4441 (define_insn "*lshrdi3_mips16"
4442 [(set (match_operand:DI 0 "register_operand" "=d,d")
4443 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4444 (match_operand:SI 2 "arith_operand" "d,I")))]
4445 "TARGET_64BIT && TARGET_MIPS16"
4446 {
4447 if (GET_CODE (operands[2]) == CONST_INT)
4448 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4449
4450 return "dsrl\t%0,%2";
4451 }
4452 [(set_attr "type" "shift")
4453 (set_attr "mode" "DI")
4454 (set_attr_alternative "length"
4455 [(const_int 4)
4456 (if_then_else (match_operand 2 "m16_uimm3_b")
4457 (const_int 4)
4458 (const_int 8))])])
4459
4460 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4461
4462 (define_split
4463 [(set (match_operand:GPR 0 "register_operand")
4464 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4465 (match_operand:GPR 2 "const_int_operand")))]
4466 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4467 && GET_CODE (operands[2]) == CONST_INT
4468 && INTVAL (operands[2]) > 8
4469 && INTVAL (operands[2]) <= 16"
4470 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4471 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4472 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4473
4474 ;; If we load a byte on the mips16 as a bitfield, the resulting
4475 ;; sequence of instructions is too complicated for combine, because it
4476 ;; involves four instructions: a load, a shift, a constant load into a
4477 ;; register, and an and (the key problem here is that the mips16 does
4478 ;; not have and immediate). We recognize a shift of a load in order
4479 ;; to make it simple enough for combine to understand.
4480 ;;
4481 ;; The length here is the worst case: the length of the split version
4482 ;; will be more accurate.
4483 (define_insn_and_split ""
4484 [(set (match_operand:SI 0 "register_operand" "=d")
4485 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4486 (match_operand:SI 2 "immediate_operand" "I")))]
4487 "TARGET_MIPS16"
4488 "#"
4489 ""
4490 [(set (match_dup 0) (match_dup 1))
4491 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4492 ""
4493 [(set_attr "type" "load")
4494 (set_attr "mode" "SI")
4495 (set_attr "length" "16")])
4496
4497 (define_insn "rotr<mode>3"
4498 [(set (match_operand:GPR 0 "register_operand" "=d")
4499 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4500 (match_operand:SI 2 "arith_operand" "dI")))]
4501 "ISA_HAS_ROR"
4502 {
4503 if (GET_CODE (operands[2]) == CONST_INT)
4504 gcc_assert (INTVAL (operands[2]) >= 0
4505 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4506
4507 return "<d>ror\t%0,%1,%2";
4508 }
4509 [(set_attr "type" "shift")
4510 (set_attr "mode" "<MODE>")])
4511 \f
4512 ;;
4513 ;; ....................
4514 ;;
4515 ;; COMPARISONS
4516 ;;
4517 ;; ....................
4518
4519 ;; Flow here is rather complex:
4520 ;;
4521 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
4522 ;; into cmp_operands[] but generates no RTL.
4523 ;;
4524 ;; 2) The appropriate branch define_expand is called, which then
4525 ;; creates the appropriate RTL for the comparison and branch.
4526 ;; Different CC modes are used, based on what type of branch is
4527 ;; done, so that we can constrain things appropriately. There
4528 ;; are assumptions in the rest of GCC that break if we fold the
4529 ;; operands into the branches for integer operations, and use cc0
4530 ;; for floating point, so we use the fp status register instead.
4531 ;; If needed, an appropriate temporary is created to hold the
4532 ;; of the integer compare.
4533
4534 (define_expand "cmp<mode>"
4535 [(set (cc0)
4536 (compare:CC (match_operand:GPR 0 "register_operand")
4537 (match_operand:GPR 1 "nonmemory_operand")))]
4538 ""
4539 {
4540 cmp_operands[0] = operands[0];
4541 cmp_operands[1] = operands[1];
4542 DONE;
4543 })
4544
4545 (define_expand "cmp<mode>"
4546 [(set (cc0)
4547 (compare:CC (match_operand:SCALARF 0 "register_operand")
4548 (match_operand:SCALARF 1 "register_operand")))]
4549 ""
4550 {
4551 cmp_operands[0] = operands[0];
4552 cmp_operands[1] = operands[1];
4553 DONE;
4554 })
4555 \f
4556 ;;
4557 ;; ....................
4558 ;;
4559 ;; CONDITIONAL BRANCHES
4560 ;;
4561 ;; ....................
4562
4563 ;; Conditional branches on floating-point equality tests.
4564
4565 (define_insn "*branch_fp"
4566 [(set (pc)
4567 (if_then_else
4568 (match_operator 0 "equality_operator"
4569 [(match_operand:CC 2 "register_operand" "z")
4570 (const_int 0)])
4571 (label_ref (match_operand 1 "" ""))
4572 (pc)))]
4573 "TARGET_HARD_FLOAT"
4574 {
4575 return mips_output_conditional_branch (insn, operands,
4576 MIPS_BRANCH ("b%F0", "%Z2%1"),
4577 MIPS_BRANCH ("b%W0", "%Z2%1"));
4578 }
4579 [(set_attr "type" "branch")
4580 (set_attr "mode" "none")])
4581
4582 (define_insn "*branch_fp_inverted"
4583 [(set (pc)
4584 (if_then_else
4585 (match_operator 0 "equality_operator"
4586 [(match_operand:CC 2 "register_operand" "z")
4587 (const_int 0)])
4588 (pc)
4589 (label_ref (match_operand 1 "" ""))))]
4590 "TARGET_HARD_FLOAT"
4591 {
4592 return mips_output_conditional_branch (insn, operands,
4593 MIPS_BRANCH ("b%W0", "%Z2%1"),
4594 MIPS_BRANCH ("b%F0", "%Z2%1"));
4595 }
4596 [(set_attr "type" "branch")
4597 (set_attr "mode" "none")])
4598
4599 ;; Conditional branches on ordered comparisons with zero.
4600
4601 (define_insn "*branch_order<mode>"
4602 [(set (pc)
4603 (if_then_else
4604 (match_operator 0 "order_operator"
4605 [(match_operand:GPR 2 "register_operand" "d")
4606 (const_int 0)])
4607 (label_ref (match_operand 1 "" ""))
4608 (pc)))]
4609 "!TARGET_MIPS16"
4610 { return mips_output_order_conditional_branch (insn, operands, false); }
4611 [(set_attr "type" "branch")
4612 (set_attr "mode" "none")])
4613
4614 (define_insn "*branch_order<mode>_inverted"
4615 [(set (pc)
4616 (if_then_else
4617 (match_operator 0 "order_operator"
4618 [(match_operand:GPR 2 "register_operand" "d")
4619 (const_int 0)])
4620 (pc)
4621 (label_ref (match_operand 1 "" ""))))]
4622 "!TARGET_MIPS16"
4623 { return mips_output_order_conditional_branch (insn, operands, true); }
4624 [(set_attr "type" "branch")
4625 (set_attr "mode" "none")])
4626
4627 ;; Conditional branch on equality comparison.
4628
4629 (define_insn "*branch_equality<mode>"
4630 [(set (pc)
4631 (if_then_else
4632 (match_operator 0 "equality_operator"
4633 [(match_operand:GPR 2 "register_operand" "d")
4634 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4635 (label_ref (match_operand 1 "" ""))
4636 (pc)))]
4637 "!TARGET_MIPS16"
4638 {
4639 return mips_output_conditional_branch (insn, operands,
4640 MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4641 MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4642 }
4643 [(set_attr "type" "branch")
4644 (set_attr "mode" "none")])
4645
4646 (define_insn "*branch_equality<mode>_inverted"
4647 [(set (pc)
4648 (if_then_else
4649 (match_operator 0 "equality_operator"
4650 [(match_operand:GPR 2 "register_operand" "d")
4651 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4652 (pc)
4653 (label_ref (match_operand 1 "" ""))))]
4654 "!TARGET_MIPS16"
4655 {
4656 return mips_output_conditional_branch (insn, operands,
4657 MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4658 MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4659 }
4660 [(set_attr "type" "branch")
4661 (set_attr "mode" "none")])
4662
4663 ;; MIPS16 branches
4664
4665 (define_insn "*branch_equality<mode>_mips16"
4666 [(set (pc)
4667 (if_then_else
4668 (match_operator 0 "equality_operator"
4669 [(match_operand:GPR 1 "register_operand" "d,t")
4670 (const_int 0)])
4671 (match_operand 2 "pc_or_label_operand" "")
4672 (match_operand 3 "pc_or_label_operand" "")))]
4673 "TARGET_MIPS16"
4674 {
4675 if (operands[2] != pc_rtx)
4676 {
4677 if (which_alternative == 0)
4678 return "b%C0z\t%1,%2";
4679 else
4680 return "bt%C0z\t%2";
4681 }
4682 else
4683 {
4684 if (which_alternative == 0)
4685 return "b%N0z\t%1,%3";
4686 else
4687 return "bt%N0z\t%3";
4688 }
4689 }
4690 [(set_attr "type" "branch")
4691 (set_attr "mode" "none")
4692 (set_attr "length" "8")])
4693
4694 (define_expand "b<code>"
4695 [(set (pc)
4696 (if_then_else (any_cond:CC (cc0)
4697 (const_int 0))
4698 (label_ref (match_operand 0 ""))
4699 (pc)))]
4700 ""
4701 {
4702 gen_conditional_branch (operands, <CODE>);
4703 DONE;
4704 })
4705
4706 ;; Used to implement built-in functions.
4707 (define_expand "condjump"
4708 [(set (pc)
4709 (if_then_else (match_operand 0)
4710 (label_ref (match_operand 1))
4711 (pc)))])
4712 \f
4713 ;;
4714 ;; ....................
4715 ;;
4716 ;; SETTING A REGISTER FROM A COMPARISON
4717 ;;
4718 ;; ....................
4719
4720 (define_expand "seq"
4721 [(set (match_operand:SI 0 "register_operand")
4722 (eq:SI (match_dup 1)
4723 (match_dup 2)))]
4724 ""
4725 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4726
4727 (define_insn "*seq_<mode>"
4728 [(set (match_operand:GPR 0 "register_operand" "=d")
4729 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4730 (const_int 0)))]
4731 "!TARGET_MIPS16"
4732 "sltu\t%0,%1,1"
4733 [(set_attr "type" "slt")
4734 (set_attr "mode" "<MODE>")])
4735
4736 (define_insn "*seq_<mode>_mips16"
4737 [(set (match_operand:GPR 0 "register_operand" "=t")
4738 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4739 (const_int 0)))]
4740 "TARGET_MIPS16"
4741 "sltu\t%1,1"
4742 [(set_attr "type" "slt")
4743 (set_attr "mode" "<MODE>")])
4744
4745 ;; "sne" uses sltu instructions in which the first operand is $0.
4746 ;; This isn't possible in mips16 code.
4747
4748 (define_expand "sne"
4749 [(set (match_operand:SI 0 "register_operand")
4750 (ne:SI (match_dup 1)
4751 (match_dup 2)))]
4752 "!TARGET_MIPS16"
4753 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4754
4755 (define_insn "*sne_<mode>"
4756 [(set (match_operand:GPR 0 "register_operand" "=d")
4757 (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4758 (const_int 0)))]
4759 "!TARGET_MIPS16"
4760 "sltu\t%0,%.,%1"
4761 [(set_attr "type" "slt")
4762 (set_attr "mode" "<MODE>")])
4763
4764 (define_expand "sgt"
4765 [(set (match_operand:SI 0 "register_operand")
4766 (gt:SI (match_dup 1)
4767 (match_dup 2)))]
4768 ""
4769 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4770
4771 (define_insn "*sgt_<mode>"
4772 [(set (match_operand:GPR 0 "register_operand" "=d")
4773 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4774 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4775 "!TARGET_MIPS16"
4776 "slt\t%0,%z2,%1"
4777 [(set_attr "type" "slt")
4778 (set_attr "mode" "<MODE>")])
4779
4780 (define_insn "*sgt_<mode>_mips16"
4781 [(set (match_operand:GPR 0 "register_operand" "=t")
4782 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4783 (match_operand:GPR 2 "register_operand" "d")))]
4784 "TARGET_MIPS16"
4785 "slt\t%2,%1"
4786 [(set_attr "type" "slt")
4787 (set_attr "mode" "<MODE>")])
4788
4789 (define_expand "sge"
4790 [(set (match_operand:SI 0 "register_operand")
4791 (ge:SI (match_dup 1)
4792 (match_dup 2)))]
4793 ""
4794 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4795
4796 (define_insn "*sge_<mode>"
4797 [(set (match_operand:GPR 0 "register_operand" "=d")
4798 (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4799 (const_int 1)))]
4800 "!TARGET_MIPS16"
4801 "slt\t%0,%.,%1"
4802 [(set_attr "type" "slt")
4803 (set_attr "mode" "<MODE>")])
4804
4805 (define_expand "slt"
4806 [(set (match_operand:SI 0 "register_operand")
4807 (lt:SI (match_dup 1)
4808 (match_dup 2)))]
4809 ""
4810 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4811
4812 (define_insn "*slt_<mode>"
4813 [(set (match_operand:GPR 0 "register_operand" "=d")
4814 (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4815 (match_operand:GPR 2 "arith_operand" "dI")))]
4816 "!TARGET_MIPS16"
4817 "slt\t%0,%1,%2"
4818 [(set_attr "type" "slt")
4819 (set_attr "mode" "<MODE>")])
4820
4821 (define_insn "*slt_<mode>_mips16"
4822 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4823 (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4824 (match_operand:GPR 2 "arith_operand" "d,I")))]
4825 "TARGET_MIPS16"
4826 "slt\t%1,%2"
4827 [(set_attr "type" "slt")
4828 (set_attr "mode" "<MODE>")
4829 (set_attr_alternative "length"
4830 [(const_int 4)
4831 (if_then_else (match_operand 2 "m16_uimm8_1")
4832 (const_int 4)
4833 (const_int 8))])])
4834
4835 (define_expand "sle"
4836 [(set (match_operand:SI 0 "register_operand")
4837 (le:SI (match_dup 1)
4838 (match_dup 2)))]
4839 ""
4840 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4841
4842 (define_insn "*sle_<mode>"
4843 [(set (match_operand:GPR 0 "register_operand" "=d")
4844 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4845 (match_operand:GPR 2 "sle_operand" "")))]
4846 "!TARGET_MIPS16"
4847 {
4848 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4849 return "slt\t%0,%1,%2";
4850 }
4851 [(set_attr "type" "slt")
4852 (set_attr "mode" "<MODE>")])
4853
4854 (define_insn "*sle_<mode>_mips16"
4855 [(set (match_operand:GPR 0 "register_operand" "=t")
4856 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4857 (match_operand:GPR 2 "sle_operand" "")))]
4858 "TARGET_MIPS16"
4859 {
4860 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4861 return "slt\t%1,%2";
4862 }
4863 [(set_attr "type" "slt")
4864 (set_attr "mode" "<MODE>")
4865 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4866 (const_int 4)
4867 (const_int 8)))])
4868
4869 (define_expand "sgtu"
4870 [(set (match_operand:SI 0 "register_operand")
4871 (gtu:SI (match_dup 1)
4872 (match_dup 2)))]
4873 ""
4874 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4875
4876 (define_insn "*sgtu_<mode>"
4877 [(set (match_operand:GPR 0 "register_operand" "=d")
4878 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4879 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4880 "!TARGET_MIPS16"
4881 "sltu\t%0,%z2,%1"
4882 [(set_attr "type" "slt")
4883 (set_attr "mode" "<MODE>")])
4884
4885 (define_insn "*sgtu_<mode>_mips16"
4886 [(set (match_operand:GPR 0 "register_operand" "=t")
4887 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4888 (match_operand:GPR 2 "register_operand" "d")))]
4889 "TARGET_MIPS16"
4890 "sltu\t%2,%1"
4891 [(set_attr "type" "slt")
4892 (set_attr "mode" "<MODE>")])
4893
4894 (define_expand "sgeu"
4895 [(set (match_operand:SI 0 "register_operand")
4896 (geu:SI (match_dup 1)
4897 (match_dup 2)))]
4898 ""
4899 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4900
4901 (define_insn "*sge_<mode>"
4902 [(set (match_operand:GPR 0 "register_operand" "=d")
4903 (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4904 (const_int 1)))]
4905 "!TARGET_MIPS16"
4906 "sltu\t%0,%.,%1"
4907 [(set_attr "type" "slt")
4908 (set_attr "mode" "<MODE>")])
4909
4910 (define_expand "sltu"
4911 [(set (match_operand:SI 0 "register_operand")
4912 (ltu:SI (match_dup 1)
4913 (match_dup 2)))]
4914 ""
4915 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4916
4917 (define_insn "*sltu_<mode>"
4918 [(set (match_operand:GPR 0 "register_operand" "=d")
4919 (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4920 (match_operand:GPR 2 "arith_operand" "dI")))]
4921 "!TARGET_MIPS16"
4922 "sltu\t%0,%1,%2"
4923 [(set_attr "type" "slt")
4924 (set_attr "mode" "<MODE>")])
4925
4926 (define_insn "*sltu_<mode>_mips16"
4927 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4928 (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4929 (match_operand:GPR 2 "arith_operand" "d,I")))]
4930 "TARGET_MIPS16"
4931 "sltu\t%1,%2"
4932 [(set_attr "type" "slt")
4933 (set_attr "mode" "<MODE>")
4934 (set_attr_alternative "length"
4935 [(const_int 4)
4936 (if_then_else (match_operand 2 "m16_uimm8_1")
4937 (const_int 4)
4938 (const_int 8))])])
4939
4940 (define_expand "sleu"
4941 [(set (match_operand:SI 0 "register_operand")
4942 (leu:SI (match_dup 1)
4943 (match_dup 2)))]
4944 ""
4945 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4946
4947 (define_insn "*sleu_<mode>"
4948 [(set (match_operand:GPR 0 "register_operand" "=d")
4949 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4950 (match_operand:GPR 2 "sleu_operand" "")))]
4951 "!TARGET_MIPS16"
4952 {
4953 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4954 return "sltu\t%0,%1,%2";
4955 }
4956 [(set_attr "type" "slt")
4957 (set_attr "mode" "<MODE>")])
4958
4959 (define_insn "*sleu_<mode>_mips16"
4960 [(set (match_operand:GPR 0 "register_operand" "=t")
4961 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4962 (match_operand:GPR 2 "sleu_operand" "")))]
4963 "TARGET_MIPS16"
4964 {
4965 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4966 return "sltu\t%1,%2";
4967 }
4968 [(set_attr "type" "slt")
4969 (set_attr "mode" "<MODE>")
4970 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4971 (const_int 4)
4972 (const_int 8)))])
4973 \f
4974 ;;
4975 ;; ....................
4976 ;;
4977 ;; FLOATING POINT COMPARISONS
4978 ;;
4979 ;; ....................
4980
4981 (define_insn "s<code>_<mode>"
4982 [(set (match_operand:CC 0 "register_operand" "=z")
4983 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4984 (match_operand:SCALARF 2 "register_operand" "f")))]
4985 ""
4986 "c.<fcond>.<fmt>\t%Z0%1,%2"
4987 [(set_attr "type" "fcmp")
4988 (set_attr "mode" "FPSW")])
4989
4990 (define_insn "s<code>_<mode>"
4991 [(set (match_operand:CC 0 "register_operand" "=z")
4992 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4993 (match_operand:SCALARF 2 "register_operand" "f")))]
4994 ""
4995 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
4996 [(set_attr "type" "fcmp")
4997 (set_attr "mode" "FPSW")])
4998 \f
4999 ;;
5000 ;; ....................
5001 ;;
5002 ;; UNCONDITIONAL BRANCHES
5003 ;;
5004 ;; ....................
5005
5006 ;; Unconditional branches.
5007
5008 (define_insn "jump"
5009 [(set (pc)
5010 (label_ref (match_operand 0 "" "")))]
5011 "!TARGET_MIPS16"
5012 {
5013 if (flag_pic)
5014 {
5015 if (get_attr_length (insn) <= 8)
5016 return "%*b\t%l0%/";
5017 else
5018 {
5019 output_asm_insn (mips_output_load_label (), operands);
5020 return "%*jr\t%@%/%]";
5021 }
5022 }
5023 else
5024 return "%*j\t%l0%/";
5025 }
5026 [(set_attr "type" "jump")
5027 (set_attr "mode" "none")
5028 (set (attr "length")
5029 ;; We can't use `j' when emitting PIC. Emit a branch if it's
5030 ;; in range, otherwise load the address of the branch target into
5031 ;; $at and then jump to it.
5032 (if_then_else
5033 (ior (eq (symbol_ref "flag_pic") (const_int 0))
5034 (lt (abs (minus (match_dup 0)
5035 (plus (pc) (const_int 4))))
5036 (const_int 131072)))
5037 (const_int 4) (const_int 16)))])
5038
5039 ;; We need a different insn for the mips16, because a mips16 branch
5040 ;; does not have a delay slot.
5041
5042 (define_insn ""
5043 [(set (pc)
5044 (label_ref (match_operand 0 "" "")))]
5045 "TARGET_MIPS16"
5046 "b\t%l0"
5047 [(set_attr "type" "branch")
5048 (set_attr "mode" "none")
5049 (set_attr "length" "8")])
5050
5051 (define_expand "indirect_jump"
5052 [(set (pc) (match_operand 0 "register_operand"))]
5053 ""
5054 {
5055 operands[0] = force_reg (Pmode, operands[0]);
5056 if (Pmode == SImode)
5057 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
5058 else
5059 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
5060 DONE;
5061 })
5062
5063 (define_insn "indirect_jump<mode>"
5064 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
5065 ""
5066 "%*j\t%0%/"
5067 [(set_attr "type" "jump")
5068 (set_attr "mode" "none")])
5069
5070 (define_expand "tablejump"
5071 [(set (pc)
5072 (match_operand 0 "register_operand"))
5073 (use (label_ref (match_operand 1 "")))]
5074 ""
5075 {
5076 if (TARGET_MIPS16)
5077 operands[0] = expand_binop (Pmode, add_optab,
5078 convert_to_mode (Pmode, operands[0], false),
5079 gen_rtx_LABEL_REF (Pmode, operands[1]),
5080 0, 0, OPTAB_WIDEN);
5081 else if (TARGET_GPWORD)
5082 operands[0] = expand_binop (Pmode, add_optab, operands[0],
5083 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
5084 else if (TARGET_RTP_PIC)
5085 {
5086 /* When generating RTP PIC, we use case table entries that are relative
5087 to the start of the function. Add the function's address to the
5088 value we loaded. */
5089 rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5090 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
5091 start, 0, 0, OPTAB_WIDEN);
5092 }
5093
5094 if (Pmode == SImode)
5095 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
5096 else
5097 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
5098 DONE;
5099 })
5100
5101 (define_insn "tablejump<mode>"
5102 [(set (pc)
5103 (match_operand:P 0 "register_operand" "d"))
5104 (use (label_ref (match_operand 1 "" "")))]
5105 ""
5106 "%*j\t%0%/"
5107 [(set_attr "type" "jump")
5108 (set_attr "mode" "none")])
5109
5110 ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
5111 ;; While it is possible to either pull it off the stack (in the
5112 ;; o32 case) or recalculate it given t9 and our target label,
5113 ;; it takes 3 or 4 insns to do so.
5114
5115 (define_expand "builtin_setjmp_setup"
5116 [(use (match_operand 0 "register_operand"))]
5117 "TARGET_USE_GOT"
5118 {
5119 rtx addr;
5120
5121 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
5122 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
5123 DONE;
5124 })
5125
5126 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
5127 ;; that older code did recalculate the gp from $25. Continue to jump through
5128 ;; $25 for compatibility (we lose nothing by doing so).
5129
5130 (define_expand "builtin_longjmp"
5131 [(use (match_operand 0 "register_operand"))]
5132 "TARGET_USE_GOT"
5133 {
5134 /* The elements of the buffer are, in order: */
5135 int W = GET_MODE_SIZE (Pmode);
5136 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5137 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
5138 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
5139 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
5140 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
5141 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
5142 The target is bound to be using $28 as the global pointer
5143 but the current function might not be. */
5144 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
5145
5146 /* This bit is similar to expand_builtin_longjmp except that it
5147 restores $gp as well. */
5148 emit_move_insn (hard_frame_pointer_rtx, fp);
5149 emit_move_insn (pv, lab);
5150 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5151 emit_move_insn (gp, gpv);
5152 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5153 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5154 emit_insn (gen_rtx_USE (VOIDmode, gp));
5155 emit_indirect_jump (pv);
5156 DONE;
5157 })
5158 \f
5159 ;;
5160 ;; ....................
5161 ;;
5162 ;; Function prologue/epilogue
5163 ;;
5164 ;; ....................
5165 ;;
5166
5167 (define_expand "prologue"
5168 [(const_int 1)]
5169 ""
5170 {
5171 mips_expand_prologue ();
5172 DONE;
5173 })
5174
5175 ;; Block any insns from being moved before this point, since the
5176 ;; profiling call to mcount can use various registers that aren't
5177 ;; saved or used to pass arguments.
5178
5179 (define_insn "blockage"
5180 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
5181 ""
5182 ""
5183 [(set_attr "type" "unknown")
5184 (set_attr "mode" "none")
5185 (set_attr "length" "0")])
5186
5187 (define_expand "epilogue"
5188 [(const_int 2)]
5189 ""
5190 {
5191 mips_expand_epilogue (false);
5192 DONE;
5193 })
5194
5195 (define_expand "sibcall_epilogue"
5196 [(const_int 2)]
5197 ""
5198 {
5199 mips_expand_epilogue (true);
5200 DONE;
5201 })
5202
5203 ;; Trivial return. Make it look like a normal return insn as that
5204 ;; allows jump optimizations to work better.
5205
5206 (define_insn "return"
5207 [(return)]
5208 "mips_can_use_return_insn ()"
5209 "%*j\t$31%/"
5210 [(set_attr "type" "jump")
5211 (set_attr "mode" "none")])
5212
5213 ;; Normal return.
5214
5215 (define_insn "return_internal"
5216 [(return)
5217 (use (match_operand 0 "pmode_register_operand" ""))]
5218 ""
5219 "%*j\t%0%/"
5220 [(set_attr "type" "jump")
5221 (set_attr "mode" "none")])
5222
5223 ;; This is used in compiling the unwind routines.
5224 (define_expand "eh_return"
5225 [(use (match_operand 0 "general_operand"))]
5226 ""
5227 {
5228 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
5229
5230 if (GET_MODE (operands[0]) != gpr_mode)
5231 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
5232 if (TARGET_64BIT)
5233 emit_insn (gen_eh_set_lr_di (operands[0]));
5234 else
5235 emit_insn (gen_eh_set_lr_si (operands[0]));
5236
5237 DONE;
5238 })
5239
5240 ;; Clobber the return address on the stack. We can't expand this
5241 ;; until we know where it will be put in the stack frame.
5242
5243 (define_insn "eh_set_lr_si"
5244 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5245 (clobber (match_scratch:SI 1 "=&d"))]
5246 "! TARGET_64BIT"
5247 "#")
5248
5249 (define_insn "eh_set_lr_di"
5250 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5251 (clobber (match_scratch:DI 1 "=&d"))]
5252 "TARGET_64BIT"
5253 "#")
5254
5255 (define_split
5256 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5257 (clobber (match_scratch 1))]
5258 "reload_completed && !TARGET_DEBUG_D_MODE"
5259 [(const_int 0)]
5260 {
5261 mips_set_return_address (operands[0], operands[1]);
5262 DONE;
5263 })
5264
5265 (define_insn_and_split "nonlocal_goto_receiver"
5266 [(set (reg:SI 28)
5267 (unspec_volatile:SI [(const_int 0)] UNSPEC_NONLOCAL_GOTO_RECEIVER))]
5268 "TARGET_CALL_CLOBBERED_GP"
5269 "#"
5270 "&& reload_completed"
5271 [(const_int 0)]
5272 {
5273 mips_restore_gp ();
5274 DONE;
5275 }
5276 [(set_attr "type" "load")
5277 (set_attr "length" "12")])
5278 \f
5279 ;;
5280 ;; ....................
5281 ;;
5282 ;; FUNCTION CALLS
5283 ;;
5284 ;; ....................
5285
5286 ;; Instructions to load a call address from the GOT. The address might
5287 ;; point to a function or to a lazy binding stub. In the latter case,
5288 ;; the stub will use the dynamic linker to resolve the function, which
5289 ;; in turn will change the GOT entry to point to the function's real
5290 ;; address.
5291 ;;
5292 ;; This means that every call, even pure and constant ones, can
5293 ;; potentially modify the GOT entry. And once a stub has been called,
5294 ;; we must not call it again.
5295 ;;
5296 ;; We represent this restriction using an imaginary fixed register that
5297 ;; acts like a GOT version number. By making the register call-clobbered,
5298 ;; we tell the target-independent code that the address could be changed
5299 ;; by any call insn.
5300 (define_insn "load_call<mode>"
5301 [(set (match_operand:P 0 "register_operand" "=d")
5302 (unspec:P [(match_operand:P 1 "register_operand" "r")
5303 (match_operand:P 2 "immediate_operand" "")
5304 (reg:P FAKE_CALL_REGNO)]
5305 UNSPEC_LOAD_CALL))]
5306 "TARGET_USE_GOT"
5307 "<load>\t%0,%R2(%1)"
5308 [(set_attr "type" "load")
5309 (set_attr "mode" "<MODE>")
5310 (set_attr "length" "4")])
5311
5312 ;; Sibling calls. All these patterns use jump instructions.
5313
5314 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5315 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
5316 ;; is defined in terms of call_insn_operand, the same is true of the
5317 ;; constraints.
5318
5319 ;; When we use an indirect jump, we need a register that will be
5320 ;; preserved by the epilogue. Since TARGET_USE_PIC_FN_ADDR_REG forces
5321 ;; us to use $25 for this purpose -- and $25 is never clobbered by the
5322 ;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG
5323 ;; as well.
5324
5325 (define_expand "sibcall"
5326 [(parallel [(call (match_operand 0 "")
5327 (match_operand 1 ""))
5328 (use (match_operand 2 "")) ;; next_arg_reg
5329 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5330 "TARGET_SIBCALLS"
5331 {
5332 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5333 DONE;
5334 })
5335
5336 (define_insn "sibcall_internal"
5337 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5338 (match_operand 1 "" ""))]
5339 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5340 { return MIPS_CALL ("j", operands, 0); }
5341 [(set_attr "type" "call")])
5342
5343 (define_expand "sibcall_value"
5344 [(parallel [(set (match_operand 0 "")
5345 (call (match_operand 1 "")
5346 (match_operand 2 "")))
5347 (use (match_operand 3 ""))])] ;; next_arg_reg
5348 "TARGET_SIBCALLS"
5349 {
5350 mips_expand_call (operands[0], XEXP (operands[1], 0),
5351 operands[2], operands[3], true);
5352 DONE;
5353 })
5354
5355 (define_insn "sibcall_value_internal"
5356 [(set (match_operand 0 "register_operand" "")
5357 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5358 (match_operand 2 "" "")))]
5359 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5360 { return MIPS_CALL ("j", operands, 1); }
5361 [(set_attr "type" "call")])
5362
5363 (define_insn "sibcall_value_multiple_internal"
5364 [(set (match_operand 0 "register_operand" "")
5365 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5366 (match_operand 2 "" "")))
5367 (set (match_operand 3 "register_operand" "")
5368 (call (mem:SI (match_dup 1))
5369 (match_dup 2)))]
5370 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5371 { return MIPS_CALL ("j", operands, 1); }
5372 [(set_attr "type" "call")])
5373
5374 (define_expand "call"
5375 [(parallel [(call (match_operand 0 "")
5376 (match_operand 1 ""))
5377 (use (match_operand 2 "")) ;; next_arg_reg
5378 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5379 ""
5380 {
5381 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5382 DONE;
5383 })
5384
5385 ;; This instruction directly corresponds to an assembly-language "jal".
5386 ;; There are four cases:
5387 ;;
5388 ;; - -mno-abicalls:
5389 ;; Both symbolic and register destinations are OK. The pattern
5390 ;; always expands to a single mips instruction.
5391 ;;
5392 ;; - -mabicalls/-mno-explicit-relocs:
5393 ;; Again, both symbolic and register destinations are OK.
5394 ;; The call is treated as a multi-instruction black box.
5395 ;;
5396 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
5397 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
5398 ;; instruction.
5399 ;;
5400 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
5401 ;; Only "jal $25" is allowed. The call is actually two instructions:
5402 ;; "jalr $25" followed by an insn to reload $gp.
5403 ;;
5404 ;; In the last case, we can generate the individual instructions with
5405 ;; a define_split. There are several things to be wary of:
5406 ;;
5407 ;; - We can't expose the load of $gp before reload. If we did,
5408 ;; it might get removed as dead, but reload can introduce new
5409 ;; uses of $gp by rematerializing constants.
5410 ;;
5411 ;; - We shouldn't restore $gp after calls that never return.
5412 ;; It isn't valid to insert instructions between a noreturn
5413 ;; call and the following barrier.
5414 ;;
5415 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
5416 ;; instruction preserves $gp and so have no effect on its liveness.
5417 ;; But once we generate the separate insns, it becomes obvious that
5418 ;; $gp is not live on entry to the call.
5419 ;;
5420 ;; ??? The operands[2] = insn check is a hack to make the original insn
5421 ;; available to the splitter.
5422 (define_insn_and_split "call_internal"
5423 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5424 (match_operand 1 "" ""))
5425 (clobber (reg:SI 31))]
5426 ""
5427 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5428 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5429 [(const_int 0)]
5430 {
5431 emit_call_insn (gen_call_split (operands[0], operands[1]));
5432 if (!find_reg_note (operands[2], REG_NORETURN, 0))
5433 mips_restore_gp ();
5434 DONE;
5435 }
5436 [(set_attr "jal" "indirect,direct")
5437 (set_attr "extended_mips16" "no,yes")])
5438
5439 (define_insn "call_split"
5440 [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5441 (match_operand 1 "" ""))
5442 (clobber (reg:SI 31))
5443 (clobber (reg:SI 28))]
5444 "TARGET_SPLIT_CALLS"
5445 { return MIPS_CALL ("jal", operands, 0); }
5446 [(set_attr "type" "call")])
5447
5448 (define_expand "call_value"
5449 [(parallel [(set (match_operand 0 "")
5450 (call (match_operand 1 "")
5451 (match_operand 2 "")))
5452 (use (match_operand 3 ""))])] ;; next_arg_reg
5453 ""
5454 {
5455 mips_expand_call (operands[0], XEXP (operands[1], 0),
5456 operands[2], operands[3], false);
5457 DONE;
5458 })
5459
5460 ;; See comment for call_internal.
5461 (define_insn_and_split "call_value_internal"
5462 [(set (match_operand 0 "register_operand" "")
5463 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5464 (match_operand 2 "" "")))
5465 (clobber (reg:SI 31))]
5466 ""
5467 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5468 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5469 [(const_int 0)]
5470 {
5471 emit_call_insn (gen_call_value_split (operands[0], operands[1],
5472 operands[2]));
5473 if (!find_reg_note (operands[3], REG_NORETURN, 0))
5474 mips_restore_gp ();
5475 DONE;
5476 }
5477 [(set_attr "jal" "indirect,direct")
5478 (set_attr "extended_mips16" "no,yes")])
5479
5480 (define_insn "call_value_split"
5481 [(set (match_operand 0 "register_operand" "")
5482 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5483 (match_operand 2 "" "")))
5484 (clobber (reg:SI 31))
5485 (clobber (reg:SI 28))]
5486 "TARGET_SPLIT_CALLS"
5487 { return MIPS_CALL ("jal", operands, 1); }
5488 [(set_attr "type" "call")])
5489
5490 ;; See comment for call_internal.
5491 (define_insn_and_split "call_value_multiple_internal"
5492 [(set (match_operand 0 "register_operand" "")
5493 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5494 (match_operand 2 "" "")))
5495 (set (match_operand 3 "register_operand" "")
5496 (call (mem:SI (match_dup 1))
5497 (match_dup 2)))
5498 (clobber (reg:SI 31))]
5499 ""
5500 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5501 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5502 [(const_int 0)]
5503 {
5504 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5505 operands[2], operands[3]));
5506 if (!find_reg_note (operands[4], REG_NORETURN, 0))
5507 mips_restore_gp ();
5508 DONE;
5509 }
5510 [(set_attr "jal" "indirect,direct")
5511 (set_attr "extended_mips16" "no,yes")])
5512
5513 (define_insn "call_value_multiple_split"
5514 [(set (match_operand 0 "register_operand" "")
5515 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5516 (match_operand 2 "" "")))
5517 (set (match_operand 3 "register_operand" "")
5518 (call (mem:SI (match_dup 1))
5519 (match_dup 2)))
5520 (clobber (reg:SI 31))
5521 (clobber (reg:SI 28))]
5522 "TARGET_SPLIT_CALLS"
5523 { return MIPS_CALL ("jal", operands, 1); }
5524 [(set_attr "type" "call")])
5525
5526 ;; Call subroutine returning any type.
5527
5528 (define_expand "untyped_call"
5529 [(parallel [(call (match_operand 0 "")
5530 (const_int 0))
5531 (match_operand 1 "")
5532 (match_operand 2 "")])]
5533 ""
5534 {
5535 int i;
5536
5537 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5538
5539 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5540 {
5541 rtx set = XVECEXP (operands[2], 0, i);
5542 emit_move_insn (SET_DEST (set), SET_SRC (set));
5543 }
5544
5545 emit_insn (gen_blockage ());
5546 DONE;
5547 })
5548 \f
5549 ;;
5550 ;; ....................
5551 ;;
5552 ;; MISC.
5553 ;;
5554 ;; ....................
5555 ;;
5556
5557
5558 (define_insn "prefetch"
5559 [(prefetch (match_operand:QI 0 "address_operand" "p")
5560 (match_operand 1 "const_int_operand" "n")
5561 (match_operand 2 "const_int_operand" "n"))]
5562 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5563 {
5564 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5565 return "pref\t%1,%a0";
5566 }
5567 [(set_attr "type" "prefetch")])
5568
5569 (define_insn "*prefetch_indexed_<mode>"
5570 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5571 (match_operand:P 1 "register_operand" "d"))
5572 (match_operand 2 "const_int_operand" "n")
5573 (match_operand 3 "const_int_operand" "n"))]
5574 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5575 {
5576 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5577 return "prefx\t%2,%1(%0)";
5578 }
5579 [(set_attr "type" "prefetchx")])
5580
5581 (define_insn "nop"
5582 [(const_int 0)]
5583 ""
5584 "%(nop%)"
5585 [(set_attr "type" "nop")
5586 (set_attr "mode" "none")])
5587
5588 ;; Like nop, but commented out when outside a .set noreorder block.
5589 (define_insn "hazard_nop"
5590 [(const_int 1)]
5591 ""
5592 {
5593 if (set_noreorder)
5594 return "nop";
5595 else
5596 return "#nop";
5597 }
5598 [(set_attr "type" "nop")])
5599 \f
5600 ;; MIPS4 Conditional move instructions.
5601
5602 (define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5603 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5604 (if_then_else:GPR
5605 (match_operator:MOVECC 4 "equality_operator"
5606 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5607 (const_int 0)])
5608 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5609 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5610 "ISA_HAS_CONDMOVE"
5611 "@
5612 mov%T4\t%0,%z2,%1
5613 mov%t4\t%0,%z3,%1"
5614 [(set_attr "type" "condmove")
5615 (set_attr "mode" "<GPR:MODE>")])
5616
5617 (define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5618 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5619 (if_then_else:SCALARF
5620 (match_operator:MOVECC 4 "equality_operator"
5621 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5622 (const_int 0)])
5623 (match_operand:SCALARF 2 "register_operand" "f,0")
5624 (match_operand:SCALARF 3 "register_operand" "0,f")))]
5625 "ISA_HAS_CONDMOVE"
5626 "@
5627 mov%T4.<fmt>\t%0,%2,%1
5628 mov%t4.<fmt>\t%0,%3,%1"
5629 [(set_attr "type" "condmove")
5630 (set_attr "mode" "<SCALARF:MODE>")])
5631
5632 ;; These are the main define_expand's used to make conditional moves.
5633
5634 (define_expand "mov<mode>cc"
5635 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5636 (set (match_operand:GPR 0 "register_operand")
5637 (if_then_else:GPR (match_dup 5)
5638 (match_operand:GPR 2 "reg_or_0_operand")
5639 (match_operand:GPR 3 "reg_or_0_operand")))]
5640 "ISA_HAS_CONDMOVE"
5641 {
5642 gen_conditional_move (operands);
5643 DONE;
5644 })
5645
5646 (define_expand "mov<mode>cc"
5647 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5648 (set (match_operand:SCALARF 0 "register_operand")
5649 (if_then_else:SCALARF (match_dup 5)
5650 (match_operand:SCALARF 2 "register_operand")
5651 (match_operand:SCALARF 3 "register_operand")))]
5652 "ISA_HAS_CONDMOVE"
5653 {
5654 gen_conditional_move (operands);
5655 DONE;
5656 })
5657 \f
5658 ;;
5659 ;; ....................
5660 ;;
5661 ;; mips16 inline constant tables
5662 ;;
5663 ;; ....................
5664 ;;
5665
5666 (define_insn "consttable_int"
5667 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5668 (match_operand 1 "const_int_operand" "")]
5669 UNSPEC_CONSTTABLE_INT)]
5670 "TARGET_MIPS16"
5671 {
5672 assemble_integer (operands[0], INTVAL (operands[1]),
5673 BITS_PER_UNIT * INTVAL (operands[1]), 1);
5674 return "";
5675 }
5676 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5677
5678 (define_insn "consttable_float"
5679 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5680 UNSPEC_CONSTTABLE_FLOAT)]
5681 "TARGET_MIPS16"
5682 {
5683 REAL_VALUE_TYPE d;
5684
5685 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5686 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5687 assemble_real (d, GET_MODE (operands[0]),
5688 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5689 return "";
5690 }
5691 [(set (attr "length")
5692 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5693
5694 (define_insn "align"
5695 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5696 ""
5697 ".align\t%0"
5698 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5699 \f
5700 (define_split
5701 [(match_operand 0 "small_data_pattern")]
5702 "reload_completed"
5703 [(match_dup 0)]
5704 { operands[0] = mips_rewrite_small_data (operands[0]); })
5705
5706 ;;
5707 ;; ....................
5708 ;;
5709 ;; MIPS16e Save/Restore
5710 ;;
5711 ;; ....................
5712 ;;
5713
5714 (define_insn "*mips16e_save_restore"
5715 [(match_parallel 0 ""
5716 [(set (match_operand:SI 1 "register_operand")
5717 (plus:SI (match_dup 1)
5718 (match_operand:SI 2 "const_int_operand")))])]
5719 "operands[1] == stack_pointer_rtx
5720 && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
5721 { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
5722 [(set_attr "type" "arith")
5723 (set_attr "extended_mips16" "yes")])
5724
5725 ; Thread-Local Storage
5726
5727 ; The TLS base pointer is accessed via "rdhwr $v1, $29". No current
5728 ; MIPS architecture defines this register, and no current
5729 ; implementation provides it; instead, any OS which supports TLS is
5730 ; expected to trap and emulate this instruction. rdhwr is part of the
5731 ; MIPS 32r2 specification, but we use it on any architecture because
5732 ; we expect it to be emulated. Use .set to force the assembler to
5733 ; accept it.
5734
5735 (define_insn "tls_get_tp_<mode>"
5736 [(set (match_operand:P 0 "register_operand" "=v")
5737 (unspec:P [(const_int 0)]
5738 UNSPEC_TLS_GET_TP))]
5739 "HAVE_AS_TLS && !TARGET_MIPS16"
5740 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5741 [(set_attr "type" "unknown")
5742 ; Since rdhwr always generates a trap for now, putting it in a delay
5743 ; slot would make the kernel's emulation of it much slower.
5744 (set_attr "can_delay" "no")
5745 (set_attr "mode" "<MODE>")])
5746 \f
5747 ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5748
5749 (include "mips-ps-3d.md")
5750
5751 ; The MIPS DSP Instructions.
5752
5753 (include "mips-dsp.md")
5754
5755 ; The MIPS DSP REV 2 Instructions.
5756
5757 (include "mips-dspr2.md")