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