Deleted Added
full compact
mips.md (169690) mips.md (208737)
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 Free Software Foundation, Inc.
4;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5;; Changes by Michael Meissner, meissner@osf.org
6;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7;; Brendan Eich, brendan@microunity.com.
8
9;; This file is part of GCC.
10
11;; GCC is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GCC is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GCC; see the file COPYING. If not, write to
23;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
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_EH_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
51 (UNSPEC_ADDRESS_FIRST 100)
52
53 (FAKE_CALL_REGNO 79)
54
55 ;; For MIPS Paired-Singled Floating Point Instructions.
56
57 (UNSPEC_MOVE_TF_PS 200)
58 (UNSPEC_C 201)
59
60 ;; MIPS64/MIPS32R2 alnv.ps
61 (UNSPEC_ALNV_PS 202)
62
63 ;; MIPS-3D instructions
64 (UNSPEC_CABS 203)
65
66 (UNSPEC_ADDR_PS 204)
67 (UNSPEC_CVT_PW_PS 205)
68 (UNSPEC_CVT_PS_PW 206)
69 (UNSPEC_MULR_PS 207)
70 (UNSPEC_ABS_PS 208)
71
72 (UNSPEC_RSQRT1 209)
73 (UNSPEC_RSQRT2 210)
74 (UNSPEC_RECIP1 211)
75 (UNSPEC_RECIP2 212)
76 (UNSPEC_SINGLE_CC 213)
77 (UNSPEC_SCC 214)
78
79 ;; MIPS DSP ASE Revision 0.98 3/24/2005
80 (UNSPEC_ADDQ 300)
81 (UNSPEC_ADDQ_S 301)
82 (UNSPEC_SUBQ 302)
83 (UNSPEC_SUBQ_S 303)
84 (UNSPEC_ADDSC 304)
85 (UNSPEC_ADDWC 305)
86 (UNSPEC_MODSUB 306)
87 (UNSPEC_RADDU_W_QB 307)
88 (UNSPEC_ABSQ_S 308)
89 (UNSPEC_PRECRQ_QB_PH 309)
90 (UNSPEC_PRECRQ_PH_W 310)
91 (UNSPEC_PRECRQ_RS_PH_W 311)
92 (UNSPEC_PRECRQU_S_QB_PH 312)
93 (UNSPEC_PRECEQ_W_PHL 313)
94 (UNSPEC_PRECEQ_W_PHR 314)
95 (UNSPEC_PRECEQU_PH_QBL 315)
96 (UNSPEC_PRECEQU_PH_QBR 316)
97 (UNSPEC_PRECEQU_PH_QBLA 317)
98 (UNSPEC_PRECEQU_PH_QBRA 318)
99 (UNSPEC_PRECEU_PH_QBL 319)
100 (UNSPEC_PRECEU_PH_QBR 320)
101 (UNSPEC_PRECEU_PH_QBLA 321)
102 (UNSPEC_PRECEU_PH_QBRA 322)
103 (UNSPEC_SHLL 323)
104 (UNSPEC_SHLL_S 324)
105 (UNSPEC_SHRL_QB 325)
106 (UNSPEC_SHRA_PH 326)
107 (UNSPEC_SHRA_R 327)
108 (UNSPEC_MULEU_S_PH_QBL 328)
109 (UNSPEC_MULEU_S_PH_QBR 329)
110 (UNSPEC_MULQ_RS_PH 330)
111 (UNSPEC_MULEQ_S_W_PHL 331)
112 (UNSPEC_MULEQ_S_W_PHR 332)
113 (UNSPEC_DPAU_H_QBL 333)
114 (UNSPEC_DPAU_H_QBR 334)
115 (UNSPEC_DPSU_H_QBL 335)
116 (UNSPEC_DPSU_H_QBR 336)
117 (UNSPEC_DPAQ_S_W_PH 337)
118 (UNSPEC_DPSQ_S_W_PH 338)
119 (UNSPEC_MULSAQ_S_W_PH 339)
120 (UNSPEC_DPAQ_SA_L_W 340)
121 (UNSPEC_DPSQ_SA_L_W 341)
122 (UNSPEC_MAQ_S_W_PHL 342)
123 (UNSPEC_MAQ_S_W_PHR 343)
124 (UNSPEC_MAQ_SA_W_PHL 344)
125 (UNSPEC_MAQ_SA_W_PHR 345)
126 (UNSPEC_BITREV 346)
127 (UNSPEC_INSV 347)
128 (UNSPEC_REPL_QB 348)
129 (UNSPEC_REPL_PH 349)
130 (UNSPEC_CMP_EQ 350)
131 (UNSPEC_CMP_LT 351)
132 (UNSPEC_CMP_LE 352)
133 (UNSPEC_CMPGU_EQ_QB 353)
134 (UNSPEC_CMPGU_LT_QB 354)
135 (UNSPEC_CMPGU_LE_QB 355)
136 (UNSPEC_PICK 356)
137 (UNSPEC_PACKRL_PH 357)
138 (UNSPEC_EXTR_W 358)
139 (UNSPEC_EXTR_R_W 359)
140 (UNSPEC_EXTR_RS_W 360)
141 (UNSPEC_EXTR_S_H 361)
142 (UNSPEC_EXTP 362)
143 (UNSPEC_EXTPDP 363)
144 (UNSPEC_SHILO 364)
145 (UNSPEC_MTHLIP 365)
146 (UNSPEC_WRDSP 366)
147 (UNSPEC_RDDSP 367)
148 ]
149)
150
151(include "predicates.md")
152(include "constraints.md")
153
154;; ....................
155;;
156;; Attributes
157;;
158;; ....................
159
160(define_attr "got" "unset,xgot_high,load"
161 (const_string "unset"))
162
163;; For jal instructions, this attribute is DIRECT when the target address
164;; is symbolic and INDIRECT when it is a register.
165(define_attr "jal" "unset,direct,indirect"
166 (const_string "unset"))
167
168;; This attribute is YES if the instruction is a jal macro (not a
169;; real jal instruction).
170;;
171;; jal is always a macro for o32 and o64 abicalls because it includes an
172;; instruction to restore $gp. Direct jals are also macros for -mshared
173;; abicalls because they first load the target address into $25.
174(define_attr "jal_macro" "no,yes"
175 (cond [(eq_attr "jal" "direct")
176 (symbol_ref "TARGET_ABICALLS
177 && (TARGET_OLDABI || !TARGET_ABSOLUTE_ABICALLS)")
178 (eq_attr "jal" "indirect")
179 (symbol_ref "TARGET_ABICALLS && TARGET_OLDABI")]
180 (const_string "no")))
181
182;; Classification of each insn.
183;; branch conditional branch
184;; jump unconditional jump
185;; call unconditional call
186;; load load instruction(s)
187;; fpload floating point load
188;; fpidxload floating point indexed load
189;; store store instruction(s)
190;; fpstore floating point store
191;; fpidxstore floating point indexed store
192;; prefetch memory prefetch (register + offset)
193;; prefetchx memory indexed prefetch (register + register)
194;; condmove conditional moves
195;; xfer transfer to/from coprocessor
196;; mthilo transfer to hi/lo registers
197;; mfhilo transfer from hi/lo registers
198;; const load constant
199;; arith integer arithmetic and logical instructions
200;; shift integer shift instructions
201;; slt set less than instructions
202;; clz the clz and clo instructions
203;; trap trap if instructions
204;; imul integer multiply 2 operands
205;; imul3 integer multiply 3 operands
206;; imadd integer multiply-add
207;; idiv integer divide
208;; fmove floating point register move
209;; fadd floating point add/subtract
210;; fmul floating point multiply
211;; fmadd floating point multiply-add
212;; fdiv floating point divide
213;; frdiv floating point reciprocal divide
214;; frdiv1 floating point reciprocal divide step 1
215;; frdiv2 floating point reciprocal divide step 2
216;; fabs floating point absolute value
217;; fneg floating point negation
218;; fcmp floating point compare
219;; fcvt floating point convert
220;; fsqrt floating point square root
221;; frsqrt floating point reciprocal square root
222;; frsqrt1 floating point reciprocal square root step1
223;; frsqrt2 floating point reciprocal square root step2
224;; multi multiword sequence (or user asm statements)
225;; nop no operation
226(define_attr "type"
227 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imul3,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
228 (cond [(eq_attr "jal" "!unset") (const_string "call")
229 (eq_attr "got" "load") (const_string "load")]
230 (const_string "unknown")))
231
232;; Main data type used by the insn
233(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
234 (const_string "unknown"))
235
236;; Mode for conversion types (fcvt)
237;; I2S integer to float single (SI/DI to SF)
238;; I2D integer to float double (SI/DI to DF)
239;; S2I float to integer (SF to SI/DI)
240;; D2I float to integer (DF to SI/DI)
241;; D2S double to float single
242;; S2D float single to double
243
244(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
245 (const_string "unknown"))
246
247;; Is this an extended instruction in mips16 mode?
248(define_attr "extended_mips16" "no,yes"
249 (const_string "no"))
250
251;; Length of instruction in bytes.
252(define_attr "length" ""
253 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
254 ;; If a branch is outside this range, we have a choice of two
255 ;; sequences. For PIC, an out-of-range branch like:
256 ;;
257 ;; bne r1,r2,target
258 ;; dslot
259 ;;
260 ;; becomes the equivalent of:
261 ;;
262 ;; beq r1,r2,1f
263 ;; dslot
264 ;; la $at,target
265 ;; jr $at
266 ;; nop
267 ;; 1:
268 ;;
269 ;; where the load address can be up to three instructions long
270 ;; (lw, nop, addiu).
271 ;;
272 ;; The non-PIC case is similar except that we use a direct
273 ;; jump instead of an la/jr pair. Since the target of this
274 ;; jump is an absolute 28-bit bit address (the other bits
275 ;; coming from the address of the delay slot) this form cannot
276 ;; cross a 256MB boundary. We could provide the option of
277 ;; using la/jr in this case too, but we do not do so at
278 ;; present.
279 ;;
280 ;; Note that this value does not account for the delay slot
281 ;; instruction, whose length is added separately. If the RTL
282 ;; pattern has no explicit delay slot, mips_adjust_insn_length
283 ;; will add the length of the implicit nop. The values for
284 ;; forward and backward branches will be different as well.
285 (eq_attr "type" "branch")
286 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
287 (le (minus (pc) (match_dup 1)) (const_int 131068)))
288 (const_int 4)
289 (ne (symbol_ref "flag_pic") (const_int 0))
290 (const_int 24)
291 ] (const_int 12))
292
293 (eq_attr "got" "load")
294 (const_int 4)
295 (eq_attr "got" "xgot_high")
296 (const_int 8)
297
298 (eq_attr "type" "const")
299 (symbol_ref "mips_const_insns (operands[1]) * 4")
300 (eq_attr "type" "load,fpload")
301 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
302 (eq_attr "type" "store,fpstore")
303 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
304
305 ;; In the worst case, a call macro will take 8 instructions:
306 ;;
307 ;; lui $25,%call_hi(FOO)
308 ;; addu $25,$25,$28
309 ;; lw $25,%call_lo(FOO)($25)
310 ;; nop
311 ;; jalr $25
312 ;; nop
313 ;; lw $gp,X($sp)
314 ;; nop
315 (eq_attr "jal_macro" "yes")
316 (const_int 32)
317
318 (and (eq_attr "extended_mips16" "yes")
319 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
320 (const_int 8)
321
322 ;; Various VR4120 errata require a nop to be inserted after a macc
323 ;; instruction. The assembler does this for us, so account for
324 ;; the worst-case length here.
325 (and (eq_attr "type" "imadd")
326 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
327 (const_int 8)
328
329 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
330 ;; the result of the second one is missed. The assembler should work
331 ;; around this by inserting a nop after the first dmult.
332 (and (eq_attr "type" "imul,imul3")
333 (and (eq_attr "mode" "DI")
334 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
335 (const_int 8)
336
337 (eq_attr "type" "idiv")
338 (symbol_ref "mips_idiv_insns () * 4")
339 ] (const_int 4)))
340
341;; Attribute describing the processor. This attribute must match exactly
342;; with the processor_type enumeration in mips.h.
343(define_attr "cpu"
344 "r3000,4kc,4kp,5kc,5kf,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
345 (const (symbol_ref "mips_tune")))
346
347;; The type of hardware hazard associated with this instruction.
348;; DELAY means that the next instruction cannot read the result
349;; of this one. HILO means that the next two instructions cannot
350;; write to HI or LO.
351(define_attr "hazard" "none,delay,hilo"
352 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
353 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
354 (const_string "delay")
355
356 (and (eq_attr "type" "xfer")
357 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
358 (const_string "delay")
359
360 (and (eq_attr "type" "fcmp")
361 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
362 (const_string "delay")
363
364 ;; The r4000 multiplication patterns include an mflo instruction.
365 (and (eq_attr "type" "imul")
366 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
367 (const_string "hilo")
368
369 (and (eq_attr "type" "mfhilo")
370 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
371 (const_string "hilo")]
372 (const_string "none")))
373
374;; Is it a single instruction?
375(define_attr "single_insn" "no,yes"
376 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
377
378;; Can the instruction be put into a delay slot?
379(define_attr "can_delay" "no,yes"
380 (if_then_else (and (eq_attr "type" "!branch,call,jump")
381 (and (eq_attr "hazard" "none")
382 (eq_attr "single_insn" "yes")))
383 (const_string "yes")
384 (const_string "no")))
385
386;; Attribute defining whether or not we can use the branch-likely instructions
387(define_attr "branch_likely" "no,yes"
388 (const
389 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
390 (const_string "yes")
391 (const_string "no"))))
392
393;; True if an instruction might assign to hi or lo when reloaded.
394;; This is used by the TUNE_MACC_CHAINS code.
395(define_attr "may_clobber_hilo" "no,yes"
396 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
397 (const_string "yes")
398 (const_string "no")))
399
400;; Describe a user's asm statement.
401(define_asm_attributes
402 [(set_attr "type" "multi")
403 (set_attr "can_delay" "no")])
404
405;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
406;; from the same template.
407(define_mode_macro GPR [SI (DI "TARGET_64BIT")])
408
409;; This mode macro allows :P to be used for patterns that operate on
410;; pointer-sized quantities. Exactly one of the two alternatives will match.
411(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
412
413;; This mode macro allows :MOVECC to be used anywhere that a
414;; conditional-move-type condition is needed.
415(define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
416
417;; This mode macro allows the QI and HI extension patterns to be defined from
418;; the same template.
419(define_mode_macro SHORT [QI HI])
420
421;; This mode macro allows :ANYF to be used wherever a scalar or vector
422;; floating-point mode is allowed.
423(define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
424 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
425 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
426
427;; Like ANYF, but only applies to scalar modes.
428(define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
429 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
430
431;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
432;; 32-bit version and "dsubu" in the 64-bit version.
433(define_mode_attr d [(SI "") (DI "d")])
434
435;; This attribute gives the length suffix for a sign- or zero-extension
436;; instruction.
437(define_mode_attr size [(QI "b") (HI "h")])
438
439;; This attributes gives the mode mask of a SHORT.
440(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
441
442;; Mode attributes for GPR loads and stores.
443(define_mode_attr load [(SI "lw") (DI "ld")])
444(define_mode_attr store [(SI "sw") (DI "sd")])
445
446;; Similarly for MIPS IV indexed FPR loads and stores.
447(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
448(define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
449
450;; The unextended ranges of the MIPS16 addiu and daddiu instructions
451;; are different. Some forms of unextended addiu have an 8-bit immediate
452;; field but the equivalent daddiu has only a 5-bit field.
453(define_mode_attr si8_di5 [(SI "8") (DI "5")])
454
455;; This attribute gives the best constraint to use for registers of
456;; a given mode.
457(define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
458
459;; This attribute gives the format suffix for floating-point operations.
460(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
461
462;; This attribute gives the upper-case mode name for one unit of a
463;; floating-point mode.
464(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
465
466;; This attribute works around the early SB-1 rev2 core "F2" erratum:
467;;
468;; In certain cases, div.s and div.ps may have a rounding error
469;; and/or wrong inexact flag.
470;;
471;; Therefore, we only allow div.s if not working around SB-1 rev2
472;; errata or if a slight loss of precision is OK.
473(define_mode_attr divide_condition
474 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
475 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
476
477; This attribute gives the condition for which sqrt instructions exist.
478(define_mode_attr sqrt_condition
479 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
480
481; This attribute gives the condition for which recip and rsqrt instructions
482; exist.
483(define_mode_attr recip_condition
484 [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
485
486;; This code macro allows all branch instructions to be generated from
487;; a single define_expand template.
488(define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
489 eq ne gt ge lt le gtu geu ltu leu])
490
491;; This code macro allows signed and unsigned widening multiplications
492;; to use the same template.
493(define_code_macro any_extend [sign_extend zero_extend])
494
495;; This code macro allows the three shift instructions to be generated
496;; from the same template.
497(define_code_macro any_shift [ashift ashiftrt lshiftrt])
498
499;; This code macro allows all native floating-point comparisons to be
500;; generated from the same template.
501(define_code_macro fcond [unordered uneq unlt unle eq lt le])
502
503;; This code macro is used for comparisons that can be implemented
504;; by swapping the operands.
505(define_code_macro swapped_fcond [ge gt unge ungt])
506
507;; <u> expands to an empty string when doing a signed operation and
508;; "u" when doing an unsigned operation.
509(define_code_attr u [(sign_extend "") (zero_extend "u")])
510
511;; <su> is like <u>, but the signed form expands to "s" rather than "".
512(define_code_attr su [(sign_extend "s") (zero_extend "u")])
513
514;; <optab> expands to the name of the optab for a particular code.
515(define_code_attr optab [(ashift "ashl")
516 (ashiftrt "ashr")
517 (lshiftrt "lshr")])
518
519;; <insn> expands to the name of the insn that implements a particular code.
520(define_code_attr insn [(ashift "sll")
521 (ashiftrt "sra")
522 (lshiftrt "srl")])
523
524;; <fcond> is the c.cond.fmt condition associated with a particular code.
525(define_code_attr fcond [(unordered "un")
526 (uneq "ueq")
527 (unlt "ult")
528 (unle "ule")
529 (eq "eq")
530 (lt "lt")
531 (le "le")])
532
533;; Similar, but for swapped conditions.
534(define_code_attr swapped_fcond [(ge "le")
535 (gt "lt")
536 (unge "ule")
537 (ungt "ult")])
538
539;; .........................
540;;
541;; Branch, call and jump delay slots
542;;
543;; .........................
544
545(define_delay (and (eq_attr "type" "branch")
546 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
547 [(eq_attr "can_delay" "yes")
548 (nil)
549 (and (eq_attr "branch_likely" "yes")
550 (eq_attr "can_delay" "yes"))])
551
552(define_delay (eq_attr "type" "jump")
553 [(eq_attr "can_delay" "yes")
554 (nil)
555 (nil)])
556
557(define_delay (and (eq_attr "type" "call")
558 (eq_attr "jal_macro" "no"))
559 [(eq_attr "can_delay" "yes")
560 (nil)
561 (nil)])
562
563;; Pipeline descriptions.
564;;
565;; generic.md provides a fallback for processors without a specific
566;; pipeline description. It is derived from the old define_function_unit
567;; version and uses the "alu" and "imuldiv" units declared below.
568;;
569;; Some of the processor-specific files are also derived from old
570;; define_function_unit descriptions and simply override the parts of
571;; generic.md that don't apply. The other processor-specific files
572;; are self-contained.
573(define_automaton "alu,imuldiv")
574
575(define_cpu_unit "alu" "alu")
576(define_cpu_unit "imuldiv" "imuldiv")
577
578(include "4k.md")
579(include "5k.md")
580(include "24k.md")
581(include "3000.md")
582(include "4000.md")
583(include "4100.md")
584(include "4130.md")
585(include "4300.md")
586(include "4600.md")
587(include "5000.md")
588(include "5400.md")
589(include "5500.md")
590(include "6000.md")
591(include "7000.md")
592(include "9000.md")
593(include "sb1.md")
594(include "sr71k.md")
595(include "generic.md")
596
597;;
598;; ....................
599;;
600;; CONDITIONAL TRAPS
601;;
602;; ....................
603;;
604
605(define_insn "trap"
606 [(trap_if (const_int 1) (const_int 0))]
607 ""
608{
609 if (ISA_HAS_COND_TRAP)
610 return "teq\t$0,$0";
611 else if (TARGET_MIPS16)
612 return "break 0";
613 else
614 return "break";
615}
616 [(set_attr "type" "trap")])
617
618(define_expand "conditional_trap"
619 [(trap_if (match_operator 0 "comparison_operator"
620 [(match_dup 2) (match_dup 3)])
621 (match_operand 1 "const_int_operand"))]
622 "ISA_HAS_COND_TRAP"
623{
624 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
625 && operands[1] == const0_rtx)
626 {
627 mips_gen_conditional_trap (operands);
628 DONE;
629 }
630 else
631 FAIL;
632})
633
634(define_insn "*conditional_trap<mode>"
635 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
636 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
637 (match_operand:GPR 2 "arith_operand" "dI")])
638 (const_int 0))]
639 "ISA_HAS_COND_TRAP"
640 "t%C0\t%z1,%2"
641 [(set_attr "type" "trap")])
642
643;;
644;; ....................
645;;
646;; ADDITION
647;;
648;; ....................
649;;
650
651(define_insn "add<mode>3"
652 [(set (match_operand:ANYF 0 "register_operand" "=f")
653 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
654 (match_operand:ANYF 2 "register_operand" "f")))]
655 ""
656 "add.<fmt>\t%0,%1,%2"
657 [(set_attr "type" "fadd")
658 (set_attr "mode" "<UNITMODE>")])
659
660(define_expand "add<mode>3"
661 [(set (match_operand:GPR 0 "register_operand")
662 (plus:GPR (match_operand:GPR 1 "register_operand")
663 (match_operand:GPR 2 "arith_operand")))]
664 "")
665
666(define_insn "*add<mode>3"
667 [(set (match_operand:GPR 0 "register_operand" "=d,d")
668 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
669 (match_operand:GPR 2 "arith_operand" "d,Q")))]
670 "!TARGET_MIPS16"
671 "@
672 <d>addu\t%0,%1,%2
673 <d>addiu\t%0,%1,%2"
674 [(set_attr "type" "arith")
675 (set_attr "mode" "<MODE>")])
676
677;; We need to recognize MIPS16 stack pointer additions explicitly, since
678;; we don't have a constraint for $sp. These insns will be generated by
679;; the save_restore_insns functions.
680
681(define_insn "*add<mode>3_sp1"
682 [(set (reg:GPR 29)
683 (plus:GPR (reg:GPR 29)
684 (match_operand:GPR 0 "const_arith_operand" "")))]
685 "TARGET_MIPS16"
686 "<d>addiu\t%$,%$,%0"
687 [(set_attr "type" "arith")
688 (set_attr "mode" "<MODE>")
689 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
690 (const_int 4)
691 (const_int 8)))])
692
693(define_insn "*add<mode>3_sp2"
694 [(set (match_operand:GPR 0 "register_operand" "=d")
695 (plus:GPR (reg:GPR 29)
696 (match_operand:GPR 1 "const_arith_operand" "")))]
697 "TARGET_MIPS16"
698 "<d>addiu\t%0,%$,%1"
699 [(set_attr "type" "arith")
700 (set_attr "mode" "<MODE>")
701 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
702 (const_int 4)
703 (const_int 8)))])
704
705(define_insn "*add<mode>3_mips16"
706 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
707 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
708 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
709 "TARGET_MIPS16"
710 "@
711 <d>addiu\t%0,%2
712 <d>addiu\t%0,%1,%2
713 <d>addu\t%0,%1,%2"
714 [(set_attr "type" "arith")
715 (set_attr "mode" "<MODE>")
716 (set_attr_alternative "length"
717 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
718 (const_int 4)
719 (const_int 8))
720 (if_then_else (match_operand 2 "m16_simm4_1")
721 (const_int 4)
722 (const_int 8))
723 (const_int 4)])])
724
725
726;; On the mips16, we can sometimes split an add of a constant which is
727;; a 4 byte instruction into two adds which are both 2 byte
728;; instructions. There are two cases: one where we are adding a
729;; constant plus a register to another register, and one where we are
730;; simply adding a constant to a register.
731
732(define_split
733 [(set (match_operand:SI 0 "register_operand")
734 (plus:SI (match_dup 0)
735 (match_operand:SI 1 "const_int_operand")))]
736 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
737 && REG_P (operands[0])
738 && M16_REG_P (REGNO (operands[0]))
739 && GET_CODE (operands[1]) == CONST_INT
740 && ((INTVAL (operands[1]) > 0x7f
741 && INTVAL (operands[1]) <= 0x7f + 0x7f)
742 || (INTVAL (operands[1]) < - 0x80
743 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
744 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
745 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
746{
747 HOST_WIDE_INT val = INTVAL (operands[1]);
748
749 if (val >= 0)
750 {
751 operands[1] = GEN_INT (0x7f);
752 operands[2] = GEN_INT (val - 0x7f);
753 }
754 else
755 {
756 operands[1] = GEN_INT (- 0x80);
757 operands[2] = GEN_INT (val + 0x80);
758 }
759})
760
761(define_split
762 [(set (match_operand:SI 0 "register_operand")
763 (plus:SI (match_operand:SI 1 "register_operand")
764 (match_operand:SI 2 "const_int_operand")))]
765 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
766 && REG_P (operands[0])
767 && M16_REG_P (REGNO (operands[0]))
768 && REG_P (operands[1])
769 && M16_REG_P (REGNO (operands[1]))
770 && REGNO (operands[0]) != REGNO (operands[1])
771 && GET_CODE (operands[2]) == CONST_INT
772 && ((INTVAL (operands[2]) > 0x7
773 && INTVAL (operands[2]) <= 0x7 + 0x7f)
774 || (INTVAL (operands[2]) < - 0x8
775 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
776 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
777 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
778{
779 HOST_WIDE_INT val = INTVAL (operands[2]);
780
781 if (val >= 0)
782 {
783 operands[2] = GEN_INT (0x7);
784 operands[3] = GEN_INT (val - 0x7);
785 }
786 else
787 {
788 operands[2] = GEN_INT (- 0x8);
789 operands[3] = GEN_INT (val + 0x8);
790 }
791})
792
793(define_split
794 [(set (match_operand:DI 0 "register_operand")
795 (plus:DI (match_dup 0)
796 (match_operand:DI 1 "const_int_operand")))]
797 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
798 && REG_P (operands[0])
799 && M16_REG_P (REGNO (operands[0]))
800 && GET_CODE (operands[1]) == CONST_INT
801 && ((INTVAL (operands[1]) > 0xf
802 && INTVAL (operands[1]) <= 0xf + 0xf)
803 || (INTVAL (operands[1]) < - 0x10
804 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
805 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
806 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
807{
808 HOST_WIDE_INT val = INTVAL (operands[1]);
809
810 if (val >= 0)
811 {
812 operands[1] = GEN_INT (0xf);
813 operands[2] = GEN_INT (val - 0xf);
814 }
815 else
816 {
817 operands[1] = GEN_INT (- 0x10);
818 operands[2] = GEN_INT (val + 0x10);
819 }
820})
821
822(define_split
823 [(set (match_operand:DI 0 "register_operand")
824 (plus:DI (match_operand:DI 1 "register_operand")
825 (match_operand:DI 2 "const_int_operand")))]
826 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
827 && REG_P (operands[0])
828 && M16_REG_P (REGNO (operands[0]))
829 && REG_P (operands[1])
830 && M16_REG_P (REGNO (operands[1]))
831 && REGNO (operands[0]) != REGNO (operands[1])
832 && GET_CODE (operands[2]) == CONST_INT
833 && ((INTVAL (operands[2]) > 0x7
834 && INTVAL (operands[2]) <= 0x7 + 0xf)
835 || (INTVAL (operands[2]) < - 0x8
836 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
837 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
838 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
839{
840 HOST_WIDE_INT val = INTVAL (operands[2]);
841
842 if (val >= 0)
843 {
844 operands[2] = GEN_INT (0x7);
845 operands[3] = GEN_INT (val - 0x7);
846 }
847 else
848 {
849 operands[2] = GEN_INT (- 0x8);
850 operands[3] = GEN_INT (val + 0x8);
851 }
852})
853
854(define_insn "*addsi3_extended"
855 [(set (match_operand:DI 0 "register_operand" "=d,d")
856 (sign_extend:DI
857 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
858 (match_operand:SI 2 "arith_operand" "d,Q"))))]
859 "TARGET_64BIT && !TARGET_MIPS16"
860 "@
861 addu\t%0,%1,%2
862 addiu\t%0,%1,%2"
863 [(set_attr "type" "arith")
864 (set_attr "mode" "SI")])
865
866;; Split this insn so that the addiu splitters can have a crack at it.
867;; Use a conservative length estimate until the split.
868(define_insn_and_split "*addsi3_extended_mips16"
869 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
870 (sign_extend:DI
871 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
872 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
873 "TARGET_64BIT && TARGET_MIPS16"
874 "#"
875 "&& reload_completed"
876 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
877 { operands[3] = gen_lowpart (SImode, operands[0]); }
878 [(set_attr "type" "arith")
879 (set_attr "mode" "SI")
880 (set_attr "extended_mips16" "yes")])
881
882;;
883;; ....................
884;;
885;; SUBTRACTION
886;;
887;; ....................
888;;
889
890(define_insn "sub<mode>3"
891 [(set (match_operand:ANYF 0 "register_operand" "=f")
892 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
893 (match_operand:ANYF 2 "register_operand" "f")))]
894 ""
895 "sub.<fmt>\t%0,%1,%2"
896 [(set_attr "type" "fadd")
897 (set_attr "mode" "<UNITMODE>")])
898
899(define_insn "sub<mode>3"
900 [(set (match_operand:GPR 0 "register_operand" "=d")
901 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
902 (match_operand:GPR 2 "register_operand" "d")))]
903 ""
904 "<d>subu\t%0,%1,%2"
905 [(set_attr "type" "arith")
906 (set_attr "mode" "<MODE>")])
907
908(define_insn "*subsi3_extended"
909 [(set (match_operand:DI 0 "register_operand" "=d")
910 (sign_extend:DI
911 (minus:SI (match_operand:SI 1 "register_operand" "d")
912 (match_operand:SI 2 "register_operand" "d"))))]
913 "TARGET_64BIT"
914 "subu\t%0,%1,%2"
915 [(set_attr "type" "arith")
916 (set_attr "mode" "DI")])
917
918;;
919;; ....................
920;;
921;; MULTIPLICATION
922;;
923;; ....................
924;;
925
926(define_expand "mul<mode>3"
927 [(set (match_operand:SCALARF 0 "register_operand")
928 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
929 (match_operand:SCALARF 2 "register_operand")))]
930 ""
931 "")
932
933(define_insn "*mul<mode>3"
934 [(set (match_operand:SCALARF 0 "register_operand" "=f")
935 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
936 (match_operand:SCALARF 2 "register_operand" "f")))]
937 "!TARGET_4300_MUL_FIX"
938 "mul.<fmt>\t%0,%1,%2"
939 [(set_attr "type" "fmul")
940 (set_attr "mode" "<MODE>")])
941
942;; Early VR4300 silicon has a CPU bug where multiplies with certain
943;; operands may corrupt immediately following multiplies. This is a
944;; simple fix to insert NOPs.
945
946(define_insn "*mul<mode>3_r4300"
947 [(set (match_operand:SCALARF 0 "register_operand" "=f")
948 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
949 (match_operand:SCALARF 2 "register_operand" "f")))]
950 "TARGET_4300_MUL_FIX"
951 "mul.<fmt>\t%0,%1,%2\;nop"
952 [(set_attr "type" "fmul")
953 (set_attr "mode" "<MODE>")
954 (set_attr "length" "8")])
955
956(define_insn "mulv2sf3"
957 [(set (match_operand:V2SF 0 "register_operand" "=f")
958 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
959 (match_operand:V2SF 2 "register_operand" "f")))]
960 "TARGET_PAIRED_SINGLE_FLOAT"
961 "mul.ps\t%0,%1,%2"
962 [(set_attr "type" "fmul")
963 (set_attr "mode" "SF")])
964
965;; The original R4000 has a cpu bug. If a double-word or a variable
966;; shift executes while an integer multiplication is in progress, the
967;; shift may give an incorrect result. Avoid this by keeping the mflo
968;; with the mult on the R4000.
969;;
970;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
971;; (also valid for MIPS R4000MC processors):
972;;
973;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
974;; this errata description.
975;; The following code sequence causes the R4000 to incorrectly
976;; execute the Double Shift Right Arithmetic 32 (dsra32)
977;; instruction. If the dsra32 instruction is executed during an
978;; integer multiply, the dsra32 will only shift by the amount in
979;; specified in the instruction rather than the amount plus 32
980;; bits.
981;; instruction 1: mult rs,rt integer multiply
982;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
983;; right arithmetic + 32
984;; Workaround: A dsra32 instruction placed after an integer
985;; multiply should not be one of the 11 instructions after the
986;; multiply instruction."
987;;
988;; and:
989;;
990;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
991;; the following description.
992;; All extended shifts (shift by n+32) and variable shifts (32 and
993;; 64-bit versions) may produce incorrect results under the
994;; following conditions:
995;; 1) An integer multiply is currently executing
996;; 2) These types of shift instructions are executed immediately
997;; following an integer divide instruction.
998;; Workaround:
999;; 1) Make sure no integer multiply is running wihen these
1000;; instruction are executed. If this cannot be predicted at
1001;; compile time, then insert a "mfhi" to R0 instruction
1002;; immediately after the integer multiply instruction. This
1003;; will cause the integer multiply to complete before the shift
1004;; is executed.
1005;; 2) Separate integer divide and these two classes of shift
1006;; instructions by another instruction or a noop."
1007;;
1008;; These processors have PRId values of 0x00004220 and 0x00004300,
1009;; respectively.
1010
1011(define_expand "mul<mode>3"
1012 [(set (match_operand:GPR 0 "register_operand")
1013 (mult:GPR (match_operand:GPR 1 "register_operand")
1014 (match_operand:GPR 2 "register_operand")))]
1015 ""
1016{
1017 if (GENERATE_MULT3_<MODE>)
1018 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
1019 else if (!TARGET_FIX_R4000)
1020 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
1021 operands[2]));
1022 else
1023 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1024 DONE;
1025})
1026
1027(define_insn "mulsi3_mult3"
1028 [(set (match_operand:SI 0 "register_operand" "=d,l")
1029 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1030 (match_operand:SI 2 "register_operand" "d,d")))
1031 (clobber (match_scratch:SI 3 "=h,h"))
1032 (clobber (match_scratch:SI 4 "=l,X"))]
1033 "GENERATE_MULT3_SI"
1034{
1035 if (which_alternative == 1)
1036 return "mult\t%1,%2";
1037 if (TARGET_MAD
1038 || TARGET_MIPS5400
1039 || TARGET_MIPS5500
1040 || TARGET_MIPS7000
1041 || TARGET_MIPS9000
1042 || ISA_MIPS32
1043 || ISA_MIPS32R2
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 Free Software Foundation, Inc.
4;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5;; Changes by Michael Meissner, meissner@osf.org
6;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7;; Brendan Eich, brendan@microunity.com.
8
9;; This file is part of GCC.
10
11;; GCC is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GCC is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GCC; see the file COPYING. If not, write to
23;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
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_EH_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
51 (UNSPEC_ADDRESS_FIRST 100)
52
53 (FAKE_CALL_REGNO 79)
54
55 ;; For MIPS Paired-Singled Floating Point Instructions.
56
57 (UNSPEC_MOVE_TF_PS 200)
58 (UNSPEC_C 201)
59
60 ;; MIPS64/MIPS32R2 alnv.ps
61 (UNSPEC_ALNV_PS 202)
62
63 ;; MIPS-3D instructions
64 (UNSPEC_CABS 203)
65
66 (UNSPEC_ADDR_PS 204)
67 (UNSPEC_CVT_PW_PS 205)
68 (UNSPEC_CVT_PS_PW 206)
69 (UNSPEC_MULR_PS 207)
70 (UNSPEC_ABS_PS 208)
71
72 (UNSPEC_RSQRT1 209)
73 (UNSPEC_RSQRT2 210)
74 (UNSPEC_RECIP1 211)
75 (UNSPEC_RECIP2 212)
76 (UNSPEC_SINGLE_CC 213)
77 (UNSPEC_SCC 214)
78
79 ;; MIPS DSP ASE Revision 0.98 3/24/2005
80 (UNSPEC_ADDQ 300)
81 (UNSPEC_ADDQ_S 301)
82 (UNSPEC_SUBQ 302)
83 (UNSPEC_SUBQ_S 303)
84 (UNSPEC_ADDSC 304)
85 (UNSPEC_ADDWC 305)
86 (UNSPEC_MODSUB 306)
87 (UNSPEC_RADDU_W_QB 307)
88 (UNSPEC_ABSQ_S 308)
89 (UNSPEC_PRECRQ_QB_PH 309)
90 (UNSPEC_PRECRQ_PH_W 310)
91 (UNSPEC_PRECRQ_RS_PH_W 311)
92 (UNSPEC_PRECRQU_S_QB_PH 312)
93 (UNSPEC_PRECEQ_W_PHL 313)
94 (UNSPEC_PRECEQ_W_PHR 314)
95 (UNSPEC_PRECEQU_PH_QBL 315)
96 (UNSPEC_PRECEQU_PH_QBR 316)
97 (UNSPEC_PRECEQU_PH_QBLA 317)
98 (UNSPEC_PRECEQU_PH_QBRA 318)
99 (UNSPEC_PRECEU_PH_QBL 319)
100 (UNSPEC_PRECEU_PH_QBR 320)
101 (UNSPEC_PRECEU_PH_QBLA 321)
102 (UNSPEC_PRECEU_PH_QBRA 322)
103 (UNSPEC_SHLL 323)
104 (UNSPEC_SHLL_S 324)
105 (UNSPEC_SHRL_QB 325)
106 (UNSPEC_SHRA_PH 326)
107 (UNSPEC_SHRA_R 327)
108 (UNSPEC_MULEU_S_PH_QBL 328)
109 (UNSPEC_MULEU_S_PH_QBR 329)
110 (UNSPEC_MULQ_RS_PH 330)
111 (UNSPEC_MULEQ_S_W_PHL 331)
112 (UNSPEC_MULEQ_S_W_PHR 332)
113 (UNSPEC_DPAU_H_QBL 333)
114 (UNSPEC_DPAU_H_QBR 334)
115 (UNSPEC_DPSU_H_QBL 335)
116 (UNSPEC_DPSU_H_QBR 336)
117 (UNSPEC_DPAQ_S_W_PH 337)
118 (UNSPEC_DPSQ_S_W_PH 338)
119 (UNSPEC_MULSAQ_S_W_PH 339)
120 (UNSPEC_DPAQ_SA_L_W 340)
121 (UNSPEC_DPSQ_SA_L_W 341)
122 (UNSPEC_MAQ_S_W_PHL 342)
123 (UNSPEC_MAQ_S_W_PHR 343)
124 (UNSPEC_MAQ_SA_W_PHL 344)
125 (UNSPEC_MAQ_SA_W_PHR 345)
126 (UNSPEC_BITREV 346)
127 (UNSPEC_INSV 347)
128 (UNSPEC_REPL_QB 348)
129 (UNSPEC_REPL_PH 349)
130 (UNSPEC_CMP_EQ 350)
131 (UNSPEC_CMP_LT 351)
132 (UNSPEC_CMP_LE 352)
133 (UNSPEC_CMPGU_EQ_QB 353)
134 (UNSPEC_CMPGU_LT_QB 354)
135 (UNSPEC_CMPGU_LE_QB 355)
136 (UNSPEC_PICK 356)
137 (UNSPEC_PACKRL_PH 357)
138 (UNSPEC_EXTR_W 358)
139 (UNSPEC_EXTR_R_W 359)
140 (UNSPEC_EXTR_RS_W 360)
141 (UNSPEC_EXTR_S_H 361)
142 (UNSPEC_EXTP 362)
143 (UNSPEC_EXTPDP 363)
144 (UNSPEC_SHILO 364)
145 (UNSPEC_MTHLIP 365)
146 (UNSPEC_WRDSP 366)
147 (UNSPEC_RDDSP 367)
148 ]
149)
150
151(include "predicates.md")
152(include "constraints.md")
153
154;; ....................
155;;
156;; Attributes
157;;
158;; ....................
159
160(define_attr "got" "unset,xgot_high,load"
161 (const_string "unset"))
162
163;; For jal instructions, this attribute is DIRECT when the target address
164;; is symbolic and INDIRECT when it is a register.
165(define_attr "jal" "unset,direct,indirect"
166 (const_string "unset"))
167
168;; This attribute is YES if the instruction is a jal macro (not a
169;; real jal instruction).
170;;
171;; jal is always a macro for o32 and o64 abicalls because it includes an
172;; instruction to restore $gp. Direct jals are also macros for -mshared
173;; abicalls because they first load the target address into $25.
174(define_attr "jal_macro" "no,yes"
175 (cond [(eq_attr "jal" "direct")
176 (symbol_ref "TARGET_ABICALLS
177 && (TARGET_OLDABI || !TARGET_ABSOLUTE_ABICALLS)")
178 (eq_attr "jal" "indirect")
179 (symbol_ref "TARGET_ABICALLS && TARGET_OLDABI")]
180 (const_string "no")))
181
182;; Classification of each insn.
183;; branch conditional branch
184;; jump unconditional jump
185;; call unconditional call
186;; load load instruction(s)
187;; fpload floating point load
188;; fpidxload floating point indexed load
189;; store store instruction(s)
190;; fpstore floating point store
191;; fpidxstore floating point indexed store
192;; prefetch memory prefetch (register + offset)
193;; prefetchx memory indexed prefetch (register + register)
194;; condmove conditional moves
195;; xfer transfer to/from coprocessor
196;; mthilo transfer to hi/lo registers
197;; mfhilo transfer from hi/lo registers
198;; const load constant
199;; arith integer arithmetic and logical instructions
200;; shift integer shift instructions
201;; slt set less than instructions
202;; clz the clz and clo instructions
203;; trap trap if instructions
204;; imul integer multiply 2 operands
205;; imul3 integer multiply 3 operands
206;; imadd integer multiply-add
207;; idiv integer divide
208;; fmove floating point register move
209;; fadd floating point add/subtract
210;; fmul floating point multiply
211;; fmadd floating point multiply-add
212;; fdiv floating point divide
213;; frdiv floating point reciprocal divide
214;; frdiv1 floating point reciprocal divide step 1
215;; frdiv2 floating point reciprocal divide step 2
216;; fabs floating point absolute value
217;; fneg floating point negation
218;; fcmp floating point compare
219;; fcvt floating point convert
220;; fsqrt floating point square root
221;; frsqrt floating point reciprocal square root
222;; frsqrt1 floating point reciprocal square root step1
223;; frsqrt2 floating point reciprocal square root step2
224;; multi multiword sequence (or user asm statements)
225;; nop no operation
226(define_attr "type"
227 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imul3,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
228 (cond [(eq_attr "jal" "!unset") (const_string "call")
229 (eq_attr "got" "load") (const_string "load")]
230 (const_string "unknown")))
231
232;; Main data type used by the insn
233(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
234 (const_string "unknown"))
235
236;; Mode for conversion types (fcvt)
237;; I2S integer to float single (SI/DI to SF)
238;; I2D integer to float double (SI/DI to DF)
239;; S2I float to integer (SF to SI/DI)
240;; D2I float to integer (DF to SI/DI)
241;; D2S double to float single
242;; S2D float single to double
243
244(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D"
245 (const_string "unknown"))
246
247;; Is this an extended instruction in mips16 mode?
248(define_attr "extended_mips16" "no,yes"
249 (const_string "no"))
250
251;; Length of instruction in bytes.
252(define_attr "length" ""
253 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
254 ;; If a branch is outside this range, we have a choice of two
255 ;; sequences. For PIC, an out-of-range branch like:
256 ;;
257 ;; bne r1,r2,target
258 ;; dslot
259 ;;
260 ;; becomes the equivalent of:
261 ;;
262 ;; beq r1,r2,1f
263 ;; dslot
264 ;; la $at,target
265 ;; jr $at
266 ;; nop
267 ;; 1:
268 ;;
269 ;; where the load address can be up to three instructions long
270 ;; (lw, nop, addiu).
271 ;;
272 ;; The non-PIC case is similar except that we use a direct
273 ;; jump instead of an la/jr pair. Since the target of this
274 ;; jump is an absolute 28-bit bit address (the other bits
275 ;; coming from the address of the delay slot) this form cannot
276 ;; cross a 256MB boundary. We could provide the option of
277 ;; using la/jr in this case too, but we do not do so at
278 ;; present.
279 ;;
280 ;; Note that this value does not account for the delay slot
281 ;; instruction, whose length is added separately. If the RTL
282 ;; pattern has no explicit delay slot, mips_adjust_insn_length
283 ;; will add the length of the implicit nop. The values for
284 ;; forward and backward branches will be different as well.
285 (eq_attr "type" "branch")
286 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
287 (le (minus (pc) (match_dup 1)) (const_int 131068)))
288 (const_int 4)
289 (ne (symbol_ref "flag_pic") (const_int 0))
290 (const_int 24)
291 ] (const_int 12))
292
293 (eq_attr "got" "load")
294 (const_int 4)
295 (eq_attr "got" "xgot_high")
296 (const_int 8)
297
298 (eq_attr "type" "const")
299 (symbol_ref "mips_const_insns (operands[1]) * 4")
300 (eq_attr "type" "load,fpload")
301 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
302 (eq_attr "type" "store,fpstore")
303 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
304
305 ;; In the worst case, a call macro will take 8 instructions:
306 ;;
307 ;; lui $25,%call_hi(FOO)
308 ;; addu $25,$25,$28
309 ;; lw $25,%call_lo(FOO)($25)
310 ;; nop
311 ;; jalr $25
312 ;; nop
313 ;; lw $gp,X($sp)
314 ;; nop
315 (eq_attr "jal_macro" "yes")
316 (const_int 32)
317
318 (and (eq_attr "extended_mips16" "yes")
319 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
320 (const_int 8)
321
322 ;; Various VR4120 errata require a nop to be inserted after a macc
323 ;; instruction. The assembler does this for us, so account for
324 ;; the worst-case length here.
325 (and (eq_attr "type" "imadd")
326 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
327 (const_int 8)
328
329 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
330 ;; the result of the second one is missed. The assembler should work
331 ;; around this by inserting a nop after the first dmult.
332 (and (eq_attr "type" "imul,imul3")
333 (and (eq_attr "mode" "DI")
334 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
335 (const_int 8)
336
337 (eq_attr "type" "idiv")
338 (symbol_ref "mips_idiv_insns () * 4")
339 ] (const_int 4)))
340
341;; Attribute describing the processor. This attribute must match exactly
342;; with the processor_type enumeration in mips.h.
343(define_attr "cpu"
344 "r3000,4kc,4kp,5kc,5kf,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000"
345 (const (symbol_ref "mips_tune")))
346
347;; The type of hardware hazard associated with this instruction.
348;; DELAY means that the next instruction cannot read the result
349;; of this one. HILO means that the next two instructions cannot
350;; write to HI or LO.
351(define_attr "hazard" "none,delay,hilo"
352 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
353 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
354 (const_string "delay")
355
356 (and (eq_attr "type" "xfer")
357 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
358 (const_string "delay")
359
360 (and (eq_attr "type" "fcmp")
361 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
362 (const_string "delay")
363
364 ;; The r4000 multiplication patterns include an mflo instruction.
365 (and (eq_attr "type" "imul")
366 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
367 (const_string "hilo")
368
369 (and (eq_attr "type" "mfhilo")
370 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
371 (const_string "hilo")]
372 (const_string "none")))
373
374;; Is it a single instruction?
375(define_attr "single_insn" "no,yes"
376 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
377
378;; Can the instruction be put into a delay slot?
379(define_attr "can_delay" "no,yes"
380 (if_then_else (and (eq_attr "type" "!branch,call,jump")
381 (and (eq_attr "hazard" "none")
382 (eq_attr "single_insn" "yes")))
383 (const_string "yes")
384 (const_string "no")))
385
386;; Attribute defining whether or not we can use the branch-likely instructions
387(define_attr "branch_likely" "no,yes"
388 (const
389 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
390 (const_string "yes")
391 (const_string "no"))))
392
393;; True if an instruction might assign to hi or lo when reloaded.
394;; This is used by the TUNE_MACC_CHAINS code.
395(define_attr "may_clobber_hilo" "no,yes"
396 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo")
397 (const_string "yes")
398 (const_string "no")))
399
400;; Describe a user's asm statement.
401(define_asm_attributes
402 [(set_attr "type" "multi")
403 (set_attr "can_delay" "no")])
404
405;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
406;; from the same template.
407(define_mode_macro GPR [SI (DI "TARGET_64BIT")])
408
409;; This mode macro allows :P to be used for patterns that operate on
410;; pointer-sized quantities. Exactly one of the two alternatives will match.
411(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
412
413;; This mode macro allows :MOVECC to be used anywhere that a
414;; conditional-move-type condition is needed.
415(define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
416
417;; This mode macro allows the QI and HI extension patterns to be defined from
418;; the same template.
419(define_mode_macro SHORT [QI HI])
420
421;; This mode macro allows :ANYF to be used wherever a scalar or vector
422;; floating-point mode is allowed.
423(define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
424 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
425 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
426
427;; Like ANYF, but only applies to scalar modes.
428(define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
429 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
430
431;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
432;; 32-bit version and "dsubu" in the 64-bit version.
433(define_mode_attr d [(SI "") (DI "d")])
434
435;; This attribute gives the length suffix for a sign- or zero-extension
436;; instruction.
437(define_mode_attr size [(QI "b") (HI "h")])
438
439;; This attributes gives the mode mask of a SHORT.
440(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
441
442;; Mode attributes for GPR loads and stores.
443(define_mode_attr load [(SI "lw") (DI "ld")])
444(define_mode_attr store [(SI "sw") (DI "sd")])
445
446;; Similarly for MIPS IV indexed FPR loads and stores.
447(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
448(define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
449
450;; The unextended ranges of the MIPS16 addiu and daddiu instructions
451;; are different. Some forms of unextended addiu have an 8-bit immediate
452;; field but the equivalent daddiu has only a 5-bit field.
453(define_mode_attr si8_di5 [(SI "8") (DI "5")])
454
455;; This attribute gives the best constraint to use for registers of
456;; a given mode.
457(define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
458
459;; This attribute gives the format suffix for floating-point operations.
460(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
461
462;; This attribute gives the upper-case mode name for one unit of a
463;; floating-point mode.
464(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
465
466;; This attribute works around the early SB-1 rev2 core "F2" erratum:
467;;
468;; In certain cases, div.s and div.ps may have a rounding error
469;; and/or wrong inexact flag.
470;;
471;; Therefore, we only allow div.s if not working around SB-1 rev2
472;; errata or if a slight loss of precision is OK.
473(define_mode_attr divide_condition
474 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")
475 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")])
476
477; This attribute gives the condition for which sqrt instructions exist.
478(define_mode_attr sqrt_condition
479 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")])
480
481; This attribute gives the condition for which recip and rsqrt instructions
482; exist.
483(define_mode_attr recip_condition
484 [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")])
485
486;; This code macro allows all branch instructions to be generated from
487;; a single define_expand template.
488(define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
489 eq ne gt ge lt le gtu geu ltu leu])
490
491;; This code macro allows signed and unsigned widening multiplications
492;; to use the same template.
493(define_code_macro any_extend [sign_extend zero_extend])
494
495;; This code macro allows the three shift instructions to be generated
496;; from the same template.
497(define_code_macro any_shift [ashift ashiftrt lshiftrt])
498
499;; This code macro allows all native floating-point comparisons to be
500;; generated from the same template.
501(define_code_macro fcond [unordered uneq unlt unle eq lt le])
502
503;; This code macro is used for comparisons that can be implemented
504;; by swapping the operands.
505(define_code_macro swapped_fcond [ge gt unge ungt])
506
507;; <u> expands to an empty string when doing a signed operation and
508;; "u" when doing an unsigned operation.
509(define_code_attr u [(sign_extend "") (zero_extend "u")])
510
511;; <su> is like <u>, but the signed form expands to "s" rather than "".
512(define_code_attr su [(sign_extend "s") (zero_extend "u")])
513
514;; <optab> expands to the name of the optab for a particular code.
515(define_code_attr optab [(ashift "ashl")
516 (ashiftrt "ashr")
517 (lshiftrt "lshr")])
518
519;; <insn> expands to the name of the insn that implements a particular code.
520(define_code_attr insn [(ashift "sll")
521 (ashiftrt "sra")
522 (lshiftrt "srl")])
523
524;; <fcond> is the c.cond.fmt condition associated with a particular code.
525(define_code_attr fcond [(unordered "un")
526 (uneq "ueq")
527 (unlt "ult")
528 (unle "ule")
529 (eq "eq")
530 (lt "lt")
531 (le "le")])
532
533;; Similar, but for swapped conditions.
534(define_code_attr swapped_fcond [(ge "le")
535 (gt "lt")
536 (unge "ule")
537 (ungt "ult")])
538
539;; .........................
540;;
541;; Branch, call and jump delay slots
542;;
543;; .........................
544
545(define_delay (and (eq_attr "type" "branch")
546 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
547 [(eq_attr "can_delay" "yes")
548 (nil)
549 (and (eq_attr "branch_likely" "yes")
550 (eq_attr "can_delay" "yes"))])
551
552(define_delay (eq_attr "type" "jump")
553 [(eq_attr "can_delay" "yes")
554 (nil)
555 (nil)])
556
557(define_delay (and (eq_attr "type" "call")
558 (eq_attr "jal_macro" "no"))
559 [(eq_attr "can_delay" "yes")
560 (nil)
561 (nil)])
562
563;; Pipeline descriptions.
564;;
565;; generic.md provides a fallback for processors without a specific
566;; pipeline description. It is derived from the old define_function_unit
567;; version and uses the "alu" and "imuldiv" units declared below.
568;;
569;; Some of the processor-specific files are also derived from old
570;; define_function_unit descriptions and simply override the parts of
571;; generic.md that don't apply. The other processor-specific files
572;; are self-contained.
573(define_automaton "alu,imuldiv")
574
575(define_cpu_unit "alu" "alu")
576(define_cpu_unit "imuldiv" "imuldiv")
577
578(include "4k.md")
579(include "5k.md")
580(include "24k.md")
581(include "3000.md")
582(include "4000.md")
583(include "4100.md")
584(include "4130.md")
585(include "4300.md")
586(include "4600.md")
587(include "5000.md")
588(include "5400.md")
589(include "5500.md")
590(include "6000.md")
591(include "7000.md")
592(include "9000.md")
593(include "sb1.md")
594(include "sr71k.md")
595(include "generic.md")
596
597;;
598;; ....................
599;;
600;; CONDITIONAL TRAPS
601;;
602;; ....................
603;;
604
605(define_insn "trap"
606 [(trap_if (const_int 1) (const_int 0))]
607 ""
608{
609 if (ISA_HAS_COND_TRAP)
610 return "teq\t$0,$0";
611 else if (TARGET_MIPS16)
612 return "break 0";
613 else
614 return "break";
615}
616 [(set_attr "type" "trap")])
617
618(define_expand "conditional_trap"
619 [(trap_if (match_operator 0 "comparison_operator"
620 [(match_dup 2) (match_dup 3)])
621 (match_operand 1 "const_int_operand"))]
622 "ISA_HAS_COND_TRAP"
623{
624 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
625 && operands[1] == const0_rtx)
626 {
627 mips_gen_conditional_trap (operands);
628 DONE;
629 }
630 else
631 FAIL;
632})
633
634(define_insn "*conditional_trap<mode>"
635 [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
636 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
637 (match_operand:GPR 2 "arith_operand" "dI")])
638 (const_int 0))]
639 "ISA_HAS_COND_TRAP"
640 "t%C0\t%z1,%2"
641 [(set_attr "type" "trap")])
642
643;;
644;; ....................
645;;
646;; ADDITION
647;;
648;; ....................
649;;
650
651(define_insn "add<mode>3"
652 [(set (match_operand:ANYF 0 "register_operand" "=f")
653 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
654 (match_operand:ANYF 2 "register_operand" "f")))]
655 ""
656 "add.<fmt>\t%0,%1,%2"
657 [(set_attr "type" "fadd")
658 (set_attr "mode" "<UNITMODE>")])
659
660(define_expand "add<mode>3"
661 [(set (match_operand:GPR 0 "register_operand")
662 (plus:GPR (match_operand:GPR 1 "register_operand")
663 (match_operand:GPR 2 "arith_operand")))]
664 "")
665
666(define_insn "*add<mode>3"
667 [(set (match_operand:GPR 0 "register_operand" "=d,d")
668 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
669 (match_operand:GPR 2 "arith_operand" "d,Q")))]
670 "!TARGET_MIPS16"
671 "@
672 <d>addu\t%0,%1,%2
673 <d>addiu\t%0,%1,%2"
674 [(set_attr "type" "arith")
675 (set_attr "mode" "<MODE>")])
676
677;; We need to recognize MIPS16 stack pointer additions explicitly, since
678;; we don't have a constraint for $sp. These insns will be generated by
679;; the save_restore_insns functions.
680
681(define_insn "*add<mode>3_sp1"
682 [(set (reg:GPR 29)
683 (plus:GPR (reg:GPR 29)
684 (match_operand:GPR 0 "const_arith_operand" "")))]
685 "TARGET_MIPS16"
686 "<d>addiu\t%$,%$,%0"
687 [(set_attr "type" "arith")
688 (set_attr "mode" "<MODE>")
689 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
690 (const_int 4)
691 (const_int 8)))])
692
693(define_insn "*add<mode>3_sp2"
694 [(set (match_operand:GPR 0 "register_operand" "=d")
695 (plus:GPR (reg:GPR 29)
696 (match_operand:GPR 1 "const_arith_operand" "")))]
697 "TARGET_MIPS16"
698 "<d>addiu\t%0,%$,%1"
699 [(set_attr "type" "arith")
700 (set_attr "mode" "<MODE>")
701 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
702 (const_int 4)
703 (const_int 8)))])
704
705(define_insn "*add<mode>3_mips16"
706 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
707 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
708 (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
709 "TARGET_MIPS16"
710 "@
711 <d>addiu\t%0,%2
712 <d>addiu\t%0,%1,%2
713 <d>addu\t%0,%1,%2"
714 [(set_attr "type" "arith")
715 (set_attr "mode" "<MODE>")
716 (set_attr_alternative "length"
717 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
718 (const_int 4)
719 (const_int 8))
720 (if_then_else (match_operand 2 "m16_simm4_1")
721 (const_int 4)
722 (const_int 8))
723 (const_int 4)])])
724
725
726;; On the mips16, we can sometimes split an add of a constant which is
727;; a 4 byte instruction into two adds which are both 2 byte
728;; instructions. There are two cases: one where we are adding a
729;; constant plus a register to another register, and one where we are
730;; simply adding a constant to a register.
731
732(define_split
733 [(set (match_operand:SI 0 "register_operand")
734 (plus:SI (match_dup 0)
735 (match_operand:SI 1 "const_int_operand")))]
736 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
737 && REG_P (operands[0])
738 && M16_REG_P (REGNO (operands[0]))
739 && GET_CODE (operands[1]) == CONST_INT
740 && ((INTVAL (operands[1]) > 0x7f
741 && INTVAL (operands[1]) <= 0x7f + 0x7f)
742 || (INTVAL (operands[1]) < - 0x80
743 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
744 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
745 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
746{
747 HOST_WIDE_INT val = INTVAL (operands[1]);
748
749 if (val >= 0)
750 {
751 operands[1] = GEN_INT (0x7f);
752 operands[2] = GEN_INT (val - 0x7f);
753 }
754 else
755 {
756 operands[1] = GEN_INT (- 0x80);
757 operands[2] = GEN_INT (val + 0x80);
758 }
759})
760
761(define_split
762 [(set (match_operand:SI 0 "register_operand")
763 (plus:SI (match_operand:SI 1 "register_operand")
764 (match_operand:SI 2 "const_int_operand")))]
765 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
766 && REG_P (operands[0])
767 && M16_REG_P (REGNO (operands[0]))
768 && REG_P (operands[1])
769 && M16_REG_P (REGNO (operands[1]))
770 && REGNO (operands[0]) != REGNO (operands[1])
771 && GET_CODE (operands[2]) == CONST_INT
772 && ((INTVAL (operands[2]) > 0x7
773 && INTVAL (operands[2]) <= 0x7 + 0x7f)
774 || (INTVAL (operands[2]) < - 0x8
775 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
776 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
777 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
778{
779 HOST_WIDE_INT val = INTVAL (operands[2]);
780
781 if (val >= 0)
782 {
783 operands[2] = GEN_INT (0x7);
784 operands[3] = GEN_INT (val - 0x7);
785 }
786 else
787 {
788 operands[2] = GEN_INT (- 0x8);
789 operands[3] = GEN_INT (val + 0x8);
790 }
791})
792
793(define_split
794 [(set (match_operand:DI 0 "register_operand")
795 (plus:DI (match_dup 0)
796 (match_operand:DI 1 "const_int_operand")))]
797 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
798 && REG_P (operands[0])
799 && M16_REG_P (REGNO (operands[0]))
800 && GET_CODE (operands[1]) == CONST_INT
801 && ((INTVAL (operands[1]) > 0xf
802 && INTVAL (operands[1]) <= 0xf + 0xf)
803 || (INTVAL (operands[1]) < - 0x10
804 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
805 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
806 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
807{
808 HOST_WIDE_INT val = INTVAL (operands[1]);
809
810 if (val >= 0)
811 {
812 operands[1] = GEN_INT (0xf);
813 operands[2] = GEN_INT (val - 0xf);
814 }
815 else
816 {
817 operands[1] = GEN_INT (- 0x10);
818 operands[2] = GEN_INT (val + 0x10);
819 }
820})
821
822(define_split
823 [(set (match_operand:DI 0 "register_operand")
824 (plus:DI (match_operand:DI 1 "register_operand")
825 (match_operand:DI 2 "const_int_operand")))]
826 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
827 && REG_P (operands[0])
828 && M16_REG_P (REGNO (operands[0]))
829 && REG_P (operands[1])
830 && M16_REG_P (REGNO (operands[1]))
831 && REGNO (operands[0]) != REGNO (operands[1])
832 && GET_CODE (operands[2]) == CONST_INT
833 && ((INTVAL (operands[2]) > 0x7
834 && INTVAL (operands[2]) <= 0x7 + 0xf)
835 || (INTVAL (operands[2]) < - 0x8
836 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
837 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
838 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
839{
840 HOST_WIDE_INT val = INTVAL (operands[2]);
841
842 if (val >= 0)
843 {
844 operands[2] = GEN_INT (0x7);
845 operands[3] = GEN_INT (val - 0x7);
846 }
847 else
848 {
849 operands[2] = GEN_INT (- 0x8);
850 operands[3] = GEN_INT (val + 0x8);
851 }
852})
853
854(define_insn "*addsi3_extended"
855 [(set (match_operand:DI 0 "register_operand" "=d,d")
856 (sign_extend:DI
857 (plus:SI (match_operand:SI 1 "register_operand" "d,d")
858 (match_operand:SI 2 "arith_operand" "d,Q"))))]
859 "TARGET_64BIT && !TARGET_MIPS16"
860 "@
861 addu\t%0,%1,%2
862 addiu\t%0,%1,%2"
863 [(set_attr "type" "arith")
864 (set_attr "mode" "SI")])
865
866;; Split this insn so that the addiu splitters can have a crack at it.
867;; Use a conservative length estimate until the split.
868(define_insn_and_split "*addsi3_extended_mips16"
869 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
870 (sign_extend:DI
871 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
872 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
873 "TARGET_64BIT && TARGET_MIPS16"
874 "#"
875 "&& reload_completed"
876 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
877 { operands[3] = gen_lowpart (SImode, operands[0]); }
878 [(set_attr "type" "arith")
879 (set_attr "mode" "SI")
880 (set_attr "extended_mips16" "yes")])
881
882;;
883;; ....................
884;;
885;; SUBTRACTION
886;;
887;; ....................
888;;
889
890(define_insn "sub<mode>3"
891 [(set (match_operand:ANYF 0 "register_operand" "=f")
892 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
893 (match_operand:ANYF 2 "register_operand" "f")))]
894 ""
895 "sub.<fmt>\t%0,%1,%2"
896 [(set_attr "type" "fadd")
897 (set_attr "mode" "<UNITMODE>")])
898
899(define_insn "sub<mode>3"
900 [(set (match_operand:GPR 0 "register_operand" "=d")
901 (minus:GPR (match_operand:GPR 1 "register_operand" "d")
902 (match_operand:GPR 2 "register_operand" "d")))]
903 ""
904 "<d>subu\t%0,%1,%2"
905 [(set_attr "type" "arith")
906 (set_attr "mode" "<MODE>")])
907
908(define_insn "*subsi3_extended"
909 [(set (match_operand:DI 0 "register_operand" "=d")
910 (sign_extend:DI
911 (minus:SI (match_operand:SI 1 "register_operand" "d")
912 (match_operand:SI 2 "register_operand" "d"))))]
913 "TARGET_64BIT"
914 "subu\t%0,%1,%2"
915 [(set_attr "type" "arith")
916 (set_attr "mode" "DI")])
917
918;;
919;; ....................
920;;
921;; MULTIPLICATION
922;;
923;; ....................
924;;
925
926(define_expand "mul<mode>3"
927 [(set (match_operand:SCALARF 0 "register_operand")
928 (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
929 (match_operand:SCALARF 2 "register_operand")))]
930 ""
931 "")
932
933(define_insn "*mul<mode>3"
934 [(set (match_operand:SCALARF 0 "register_operand" "=f")
935 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
936 (match_operand:SCALARF 2 "register_operand" "f")))]
937 "!TARGET_4300_MUL_FIX"
938 "mul.<fmt>\t%0,%1,%2"
939 [(set_attr "type" "fmul")
940 (set_attr "mode" "<MODE>")])
941
942;; Early VR4300 silicon has a CPU bug where multiplies with certain
943;; operands may corrupt immediately following multiplies. This is a
944;; simple fix to insert NOPs.
945
946(define_insn "*mul<mode>3_r4300"
947 [(set (match_operand:SCALARF 0 "register_operand" "=f")
948 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
949 (match_operand:SCALARF 2 "register_operand" "f")))]
950 "TARGET_4300_MUL_FIX"
951 "mul.<fmt>\t%0,%1,%2\;nop"
952 [(set_attr "type" "fmul")
953 (set_attr "mode" "<MODE>")
954 (set_attr "length" "8")])
955
956(define_insn "mulv2sf3"
957 [(set (match_operand:V2SF 0 "register_operand" "=f")
958 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
959 (match_operand:V2SF 2 "register_operand" "f")))]
960 "TARGET_PAIRED_SINGLE_FLOAT"
961 "mul.ps\t%0,%1,%2"
962 [(set_attr "type" "fmul")
963 (set_attr "mode" "SF")])
964
965;; The original R4000 has a cpu bug. If a double-word or a variable
966;; shift executes while an integer multiplication is in progress, the
967;; shift may give an incorrect result. Avoid this by keeping the mflo
968;; with the mult on the R4000.
969;;
970;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
971;; (also valid for MIPS R4000MC processors):
972;;
973;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
974;; this errata description.
975;; The following code sequence causes the R4000 to incorrectly
976;; execute the Double Shift Right Arithmetic 32 (dsra32)
977;; instruction. If the dsra32 instruction is executed during an
978;; integer multiply, the dsra32 will only shift by the amount in
979;; specified in the instruction rather than the amount plus 32
980;; bits.
981;; instruction 1: mult rs,rt integer multiply
982;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
983;; right arithmetic + 32
984;; Workaround: A dsra32 instruction placed after an integer
985;; multiply should not be one of the 11 instructions after the
986;; multiply instruction."
987;;
988;; and:
989;;
990;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
991;; the following description.
992;; All extended shifts (shift by n+32) and variable shifts (32 and
993;; 64-bit versions) may produce incorrect results under the
994;; following conditions:
995;; 1) An integer multiply is currently executing
996;; 2) These types of shift instructions are executed immediately
997;; following an integer divide instruction.
998;; Workaround:
999;; 1) Make sure no integer multiply is running wihen these
1000;; instruction are executed. If this cannot be predicted at
1001;; compile time, then insert a "mfhi" to R0 instruction
1002;; immediately after the integer multiply instruction. This
1003;; will cause the integer multiply to complete before the shift
1004;; is executed.
1005;; 2) Separate integer divide and these two classes of shift
1006;; instructions by another instruction or a noop."
1007;;
1008;; These processors have PRId values of 0x00004220 and 0x00004300,
1009;; respectively.
1010
1011(define_expand "mul<mode>3"
1012 [(set (match_operand:GPR 0 "register_operand")
1013 (mult:GPR (match_operand:GPR 1 "register_operand")
1014 (match_operand:GPR 2 "register_operand")))]
1015 ""
1016{
1017 if (GENERATE_MULT3_<MODE>)
1018 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
1019 else if (!TARGET_FIX_R4000)
1020 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
1021 operands[2]));
1022 else
1023 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
1024 DONE;
1025})
1026
1027(define_insn "mulsi3_mult3"
1028 [(set (match_operand:SI 0 "register_operand" "=d,l")
1029 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1030 (match_operand:SI 2 "register_operand" "d,d")))
1031 (clobber (match_scratch:SI 3 "=h,h"))
1032 (clobber (match_scratch:SI 4 "=l,X"))]
1033 "GENERATE_MULT3_SI"
1034{
1035 if (which_alternative == 1)
1036 return "mult\t%1,%2";
1037 if (TARGET_MAD
1038 || TARGET_MIPS5400
1039 || TARGET_MIPS5500
1040 || TARGET_MIPS7000
1041 || TARGET_MIPS9000
1042 || ISA_MIPS32
1043 || ISA_MIPS32R2
1044 || ISA_MIPS64)
1044 || ISA_MIPS64
1045 || ISA_MIPS64R2)
1045 return "mul\t%0,%1,%2";
1046 return "mult\t%0,%1,%2";
1047}
1048 [(set_attr "type" "imul3,imul")
1049 (set_attr "mode" "SI")])
1050
1051(define_insn "muldi3_mult3"
1052 [(set (match_operand:DI 0 "register_operand" "=d")
1053 (mult:DI (match_operand:DI 1 "register_operand" "d")
1054 (match_operand:DI 2 "register_operand" "d")))
1055 (clobber (match_scratch:DI 3 "=h"))
1056 (clobber (match_scratch:DI 4 "=l"))]
1057 "TARGET_64BIT && GENERATE_MULT3_DI"
1058 "dmult\t%0,%1,%2"
1059 [(set_attr "type" "imul3")
1060 (set_attr "mode" "DI")])
1061
1062;; If a register gets allocated to LO, and we spill to memory, the reload
1063;; will include a move from LO to a GPR. Merge it into the multiplication
1064;; if it can set the GPR directly.
1065;;
1066;; Operand 0: LO
1067;; Operand 1: GPR (1st multiplication operand)
1068;; Operand 2: GPR (2nd multiplication operand)
1069;; Operand 3: HI
1070;; Operand 4: GPR (destination)
1071(define_peephole2
1072 [(parallel
1073 [(set (match_operand:SI 0 "register_operand")
1074 (mult:SI (match_operand:SI 1 "register_operand")
1075 (match_operand:SI 2 "register_operand")))
1076 (clobber (match_operand:SI 3 "register_operand"))
1077 (clobber (scratch:SI))])
1078 (set (match_operand:SI 4 "register_operand")
1079 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1080 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1081 [(parallel
1082 [(set (match_dup 4)
1083 (mult:SI (match_dup 1)
1084 (match_dup 2)))
1085 (clobber (match_dup 3))
1086 (clobber (match_dup 0))])])
1087
1088(define_insn "mul<mode>3_internal"
1089 [(set (match_operand:GPR 0 "register_operand" "=l")
1090 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1091 (match_operand:GPR 2 "register_operand" "d")))
1092 (clobber (match_scratch:GPR 3 "=h"))]
1093 "!TARGET_FIX_R4000"
1094 "<d>mult\t%1,%2"
1095 [(set_attr "type" "imul")
1096 (set_attr "mode" "<MODE>")])
1097
1098(define_insn "mul<mode>3_r4000"
1099 [(set (match_operand:GPR 0 "register_operand" "=d")
1100 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1101 (match_operand:GPR 2 "register_operand" "d")))
1102 (clobber (match_scratch:GPR 3 "=h"))
1103 (clobber (match_scratch:GPR 4 "=l"))]
1104 "TARGET_FIX_R4000"
1105 "<d>mult\t%1,%2\;mflo\t%0"
1106 [(set_attr "type" "imul")
1107 (set_attr "mode" "<MODE>")
1108 (set_attr "length" "8")])
1109
1110;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1111;; of "mult; mflo". They have the same latency, but the first form gives
1112;; us an extra cycle to compute the operands.
1113
1114;; Operand 0: LO
1115;; Operand 1: GPR (1st multiplication operand)
1116;; Operand 2: GPR (2nd multiplication operand)
1117;; Operand 3: HI
1118;; Operand 4: GPR (destination)
1119(define_peephole2
1120 [(parallel
1121 [(set (match_operand:SI 0 "register_operand")
1122 (mult:SI (match_operand:SI 1 "register_operand")
1123 (match_operand:SI 2 "register_operand")))
1124 (clobber (match_operand:SI 3 "register_operand"))])
1125 (set (match_operand:SI 4 "register_operand")
1126 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1127 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1128 [(set (match_dup 0)
1129 (const_int 0))
1130 (parallel
1131 [(set (match_dup 0)
1132 (plus:SI (mult:SI (match_dup 1)
1133 (match_dup 2))
1134 (match_dup 0)))
1135 (set (match_dup 4)
1136 (plus:SI (mult:SI (match_dup 1)
1137 (match_dup 2))
1138 (match_dup 0)))
1139 (clobber (match_dup 3))])])
1140
1141;; Multiply-accumulate patterns
1142
1143;; For processors that can copy the output to a general register:
1144;;
1145;; The all-d alternative is needed because the combiner will find this
1146;; pattern and then register alloc/reload will move registers around to
1147;; make them fit, and we don't want to trigger unnecessary loads to LO.
1148;;
1149;; The last alternative should be made slightly less desirable, but adding
1150;; "?" to the constraint is too strong, and causes values to be loaded into
1151;; LO even when that's more costly. For now, using "*d" mostly does the
1152;; trick.
1153(define_insn "*mul_acc_si"
1154 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1155 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1156 (match_operand:SI 2 "register_operand" "d,d,d"))
1157 (match_operand:SI 3 "register_operand" "0,l,*d")))
1158 (clobber (match_scratch:SI 4 "=h,h,h"))
1159 (clobber (match_scratch:SI 5 "=X,3,l"))
1160 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1161 "(TARGET_MIPS3900
1162 || ISA_HAS_MADD_MSUB)
1163 && !TARGET_MIPS16"
1164{
1165 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1166 if (which_alternative == 2)
1167 return "#";
1168 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1169 return "#";
1170 return madd[which_alternative];
1171}
1172 [(set_attr "type" "imadd,imadd,multi")
1173 (set_attr "mode" "SI")
1174 (set_attr "length" "4,4,8")])
1175
1176;; Split the above insn if we failed to get LO allocated.
1177(define_split
1178 [(set (match_operand:SI 0 "register_operand")
1179 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1180 (match_operand:SI 2 "register_operand"))
1181 (match_operand:SI 3 "register_operand")))
1182 (clobber (match_scratch:SI 4))
1183 (clobber (match_scratch:SI 5))
1184 (clobber (match_scratch:SI 6))]
1185 "reload_completed && !TARGET_DEBUG_D_MODE
1186 && GP_REG_P (true_regnum (operands[0]))
1187 && GP_REG_P (true_regnum (operands[3]))"
1188 [(parallel [(set (match_dup 6)
1189 (mult:SI (match_dup 1) (match_dup 2)))
1190 (clobber (match_dup 4))
1191 (clobber (match_dup 5))])
1192 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1193 "")
1194
1195;; Splitter to copy result of MADD to a general register
1196(define_split
1197 [(set (match_operand:SI 0 "register_operand")
1198 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1199 (match_operand:SI 2 "register_operand"))
1200 (match_operand:SI 3 "register_operand")))
1201 (clobber (match_scratch:SI 4))
1202 (clobber (match_scratch:SI 5))
1203 (clobber (match_scratch:SI 6))]
1204 "reload_completed && !TARGET_DEBUG_D_MODE
1205 && GP_REG_P (true_regnum (operands[0]))
1206 && true_regnum (operands[3]) == LO_REGNUM"
1207 [(parallel [(set (match_dup 3)
1208 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1209 (match_dup 3)))
1210 (clobber (match_dup 4))
1211 (clobber (match_dup 5))
1212 (clobber (match_dup 6))])
1213 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1214 "")
1215
1216(define_insn "*macc"
1217 [(set (match_operand:SI 0 "register_operand" "=l,d")
1218 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1219 (match_operand:SI 2 "register_operand" "d,d"))
1220 (match_operand:SI 3 "register_operand" "0,l")))
1221 (clobber (match_scratch:SI 4 "=h,h"))
1222 (clobber (match_scratch:SI 5 "=X,3"))]
1223 "ISA_HAS_MACC"
1224{
1225 if (which_alternative == 1)
1226 return "macc\t%0,%1,%2";
1227 else if (TARGET_MIPS5500)
1228 return "madd\t%1,%2";
1229 else
1230 /* The VR4130 assumes that there is a two-cycle latency between a macc
1231 that "writes" to $0 and an instruction that reads from it. We avoid
1232 this by assigning to $1 instead. */
1233 return "%[macc\t%@,%1,%2%]";
1234}
1235 [(set_attr "type" "imadd")
1236 (set_attr "mode" "SI")])
1237
1238(define_insn "*msac"
1239 [(set (match_operand:SI 0 "register_operand" "=l,d")
1240 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1241 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1242 (match_operand:SI 3 "register_operand" "d,d"))))
1243 (clobber (match_scratch:SI 4 "=h,h"))
1244 (clobber (match_scratch:SI 5 "=X,1"))]
1245 "ISA_HAS_MSAC"
1246{
1247 if (which_alternative == 1)
1248 return "msac\t%0,%2,%3";
1249 else if (TARGET_MIPS5500)
1250 return "msub\t%2,%3";
1251 else
1252 return "msac\t$0,%2,%3";
1253}
1254 [(set_attr "type" "imadd")
1255 (set_attr "mode" "SI")])
1256
1257;; An msac-like instruction implemented using negation and a macc.
1258(define_insn_and_split "*msac_using_macc"
1259 [(set (match_operand:SI 0 "register_operand" "=l,d")
1260 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1261 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1262 (match_operand:SI 3 "register_operand" "d,d"))))
1263 (clobber (match_scratch:SI 4 "=h,h"))
1264 (clobber (match_scratch:SI 5 "=X,1"))
1265 (clobber (match_scratch:SI 6 "=d,d"))]
1266 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1267 "#"
1268 "&& reload_completed"
1269 [(set (match_dup 6)
1270 (neg:SI (match_dup 3)))
1271 (parallel
1272 [(set (match_dup 0)
1273 (plus:SI (mult:SI (match_dup 2)
1274 (match_dup 6))
1275 (match_dup 1)))
1276 (clobber (match_dup 4))
1277 (clobber (match_dup 5))])]
1278 ""
1279 [(set_attr "type" "imadd")
1280 (set_attr "length" "8")])
1281
1282;; Patterns generated by the define_peephole2 below.
1283
1284(define_insn "*macc2"
1285 [(set (match_operand:SI 0 "register_operand" "=l")
1286 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1287 (match_operand:SI 2 "register_operand" "d"))
1288 (match_dup 0)))
1289 (set (match_operand:SI 3 "register_operand" "=d")
1290 (plus:SI (mult:SI (match_dup 1)
1291 (match_dup 2))
1292 (match_dup 0)))
1293 (clobber (match_scratch:SI 4 "=h"))]
1294 "ISA_HAS_MACC && reload_completed"
1295 "macc\t%3,%1,%2"
1296 [(set_attr "type" "imadd")
1297 (set_attr "mode" "SI")])
1298
1299(define_insn "*msac2"
1300 [(set (match_operand:SI 0 "register_operand" "=l")
1301 (minus:SI (match_dup 0)
1302 (mult:SI (match_operand:SI 1 "register_operand" "d")
1303 (match_operand:SI 2 "register_operand" "d"))))
1304 (set (match_operand:SI 3 "register_operand" "=d")
1305 (minus:SI (match_dup 0)
1306 (mult:SI (match_dup 1)
1307 (match_dup 2))))
1308 (clobber (match_scratch:SI 4 "=h"))]
1309 "ISA_HAS_MSAC && reload_completed"
1310 "msac\t%3,%1,%2"
1311 [(set_attr "type" "imadd")
1312 (set_attr "mode" "SI")])
1313
1314;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1315;; Similarly msac.
1316;;
1317;; Operand 0: LO
1318;; Operand 1: macc/msac
1319;; Operand 2: HI
1320;; Operand 3: GPR (destination)
1321(define_peephole2
1322 [(parallel
1323 [(set (match_operand:SI 0 "register_operand")
1324 (match_operand:SI 1 "macc_msac_operand"))
1325 (clobber (match_operand:SI 2 "register_operand"))
1326 (clobber (scratch:SI))])
1327 (set (match_operand:SI 3 "register_operand")
1328 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1329 ""
1330 [(parallel [(set (match_dup 0)
1331 (match_dup 1))
1332 (set (match_dup 3)
1333 (match_dup 1))
1334 (clobber (match_dup 2))])]
1335 "")
1336
1337;; When we have a three-address multiplication instruction, it should
1338;; be faster to do a separate multiply and add, rather than moving
1339;; something into LO in order to use a macc instruction.
1340;;
1341;; This peephole needs a scratch register to cater for the case when one
1342;; of the multiplication operands is the same as the destination.
1343;;
1344;; Operand 0: GPR (scratch)
1345;; Operand 1: LO
1346;; Operand 2: GPR (addend)
1347;; Operand 3: GPR (destination)
1348;; Operand 4: macc/msac
1349;; Operand 5: HI
1350;; Operand 6: new multiplication
1351;; Operand 7: new addition/subtraction
1352(define_peephole2
1353 [(match_scratch:SI 0 "d")
1354 (set (match_operand:SI 1 "register_operand")
1355 (match_operand:SI 2 "register_operand"))
1356 (match_dup 0)
1357 (parallel
1358 [(set (match_operand:SI 3 "register_operand")
1359 (match_operand:SI 4 "macc_msac_operand"))
1360 (clobber (match_operand:SI 5 "register_operand"))
1361 (clobber (match_dup 1))])]
1362 "GENERATE_MULT3_SI
1363 && true_regnum (operands[1]) == LO_REGNUM
1364 && peep2_reg_dead_p (2, operands[1])
1365 && GP_REG_P (true_regnum (operands[3]))"
1366 [(parallel [(set (match_dup 0)
1367 (match_dup 6))
1368 (clobber (match_dup 5))
1369 (clobber (match_dup 1))])
1370 (set (match_dup 3)
1371 (match_dup 7))]
1372{
1373 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1374 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1375 operands[2], operands[0]);
1376})
1377
1378;; Same as above, except LO is the initial target of the macc.
1379;;
1380;; Operand 0: GPR (scratch)
1381;; Operand 1: LO
1382;; Operand 2: GPR (addend)
1383;; Operand 3: macc/msac
1384;; Operand 4: HI
1385;; Operand 5: GPR (destination)
1386;; Operand 6: new multiplication
1387;; Operand 7: new addition/subtraction
1388(define_peephole2
1389 [(match_scratch:SI 0 "d")
1390 (set (match_operand:SI 1 "register_operand")
1391 (match_operand:SI 2 "register_operand"))
1392 (match_dup 0)
1393 (parallel
1394 [(set (match_dup 1)
1395 (match_operand:SI 3 "macc_msac_operand"))
1396 (clobber (match_operand:SI 4 "register_operand"))
1397 (clobber (scratch:SI))])
1398 (match_dup 0)
1399 (set (match_operand:SI 5 "register_operand")
1400 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1401 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1402 [(parallel [(set (match_dup 0)
1403 (match_dup 6))
1404 (clobber (match_dup 4))
1405 (clobber (match_dup 1))])
1406 (set (match_dup 5)
1407 (match_dup 7))]
1408{
1409 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1410 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1411 operands[2], operands[0]);
1412})
1413
1414(define_insn "*mul_sub_si"
1415 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1416 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1417 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1418 (match_operand:SI 3 "register_operand" "d,d,d"))))
1419 (clobber (match_scratch:SI 4 "=h,h,h"))
1420 (clobber (match_scratch:SI 5 "=X,1,l"))
1421 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1422 "ISA_HAS_MADD_MSUB"
1423 "@
1424 msub\t%2,%3
1425 #
1426 #"
1427 [(set_attr "type" "imadd,multi,multi")
1428 (set_attr "mode" "SI")
1429 (set_attr "length" "4,8,8")])
1430
1431;; Split the above insn if we failed to get LO allocated.
1432(define_split
1433 [(set (match_operand:SI 0 "register_operand")
1434 (minus:SI (match_operand:SI 1 "register_operand")
1435 (mult:SI (match_operand:SI 2 "register_operand")
1436 (match_operand:SI 3 "register_operand"))))
1437 (clobber (match_scratch:SI 4))
1438 (clobber (match_scratch:SI 5))
1439 (clobber (match_scratch:SI 6))]
1440 "reload_completed && !TARGET_DEBUG_D_MODE
1441 && GP_REG_P (true_regnum (operands[0]))
1442 && GP_REG_P (true_regnum (operands[1]))"
1443 [(parallel [(set (match_dup 6)
1444 (mult:SI (match_dup 2) (match_dup 3)))
1445 (clobber (match_dup 4))
1446 (clobber (match_dup 5))])
1447 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1448 "")
1449
1450;; Splitter to copy result of MSUB to a general register
1451(define_split
1452 [(set (match_operand:SI 0 "register_operand")
1453 (minus:SI (match_operand:SI 1 "register_operand")
1454 (mult:SI (match_operand:SI 2 "register_operand")
1455 (match_operand:SI 3 "register_operand"))))
1456 (clobber (match_scratch:SI 4))
1457 (clobber (match_scratch:SI 5))
1458 (clobber (match_scratch:SI 6))]
1459 "reload_completed && !TARGET_DEBUG_D_MODE
1460 && GP_REG_P (true_regnum (operands[0]))
1461 && true_regnum (operands[1]) == LO_REGNUM"
1462 [(parallel [(set (match_dup 1)
1463 (minus:SI (match_dup 1)
1464 (mult:SI (match_dup 2) (match_dup 3))))
1465 (clobber (match_dup 4))
1466 (clobber (match_dup 5))
1467 (clobber (match_dup 6))])
1468 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1469 "")
1470
1471(define_insn "*muls"
1472 [(set (match_operand:SI 0 "register_operand" "=l,d")
1473 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1474 (match_operand:SI 2 "register_operand" "d,d"))))
1475 (clobber (match_scratch:SI 3 "=h,h"))
1476 (clobber (match_scratch:SI 4 "=X,l"))]
1477 "ISA_HAS_MULS"
1478 "@
1479 muls\t$0,%1,%2
1480 muls\t%0,%1,%2"
1481 [(set_attr "type" "imul,imul3")
1482 (set_attr "mode" "SI")])
1483
1484;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1485
1486(define_expand "<u>mulsidi3"
1487 [(parallel
1488 [(set (match_operand:DI 0 "register_operand")
1489 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1490 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1491 (clobber (scratch:DI))
1492 (clobber (scratch:DI))
1493 (clobber (scratch:DI))])]
1494 "!TARGET_64BIT || !TARGET_FIX_R4000"
1495{
1496 if (!TARGET_64BIT)
1497 {
1498 if (!TARGET_FIX_R4000)
1499 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1500 operands[2]));
1501 else
1502 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1503 operands[2]));
1504 DONE;
1505 }
1506})
1507
1508(define_insn "<u>mulsidi3_32bit_internal"
1509 [(set (match_operand:DI 0 "register_operand" "=x")
1510 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1511 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1512 "!TARGET_64BIT && !TARGET_FIX_R4000"
1513 "mult<u>\t%1,%2"
1514 [(set_attr "type" "imul")
1515 (set_attr "mode" "SI")])
1516
1517(define_insn "<u>mulsidi3_32bit_r4000"
1518 [(set (match_operand:DI 0 "register_operand" "=d")
1519 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1520 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1521 (clobber (match_scratch:DI 3 "=x"))]
1522 "!TARGET_64BIT && TARGET_FIX_R4000"
1523 "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1524 [(set_attr "type" "imul")
1525 (set_attr "mode" "SI")
1526 (set_attr "length" "12")])
1527
1528(define_insn_and_split "*<u>mulsidi3_64bit"
1529 [(set (match_operand:DI 0 "register_operand" "=d")
1530 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1531 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1532 (clobber (match_scratch:DI 3 "=l"))
1533 (clobber (match_scratch:DI 4 "=h"))
1534 (clobber (match_scratch:DI 5 "=d"))]
1535 "TARGET_64BIT && !TARGET_FIX_R4000"
1536 "#"
1537 "&& reload_completed"
1538 [(parallel
1539 [(set (match_dup 3)
1540 (sign_extend:DI
1541 (mult:SI (match_dup 1)
1542 (match_dup 2))))
1543 (set (match_dup 4)
1544 (ashiftrt:DI
1545 (mult:DI (any_extend:DI (match_dup 1))
1546 (any_extend:DI (match_dup 2)))
1547 (const_int 32)))])
1548
1549 ;; OP5 <- LO, OP0 <- HI
1550 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1551 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1552
1553 ;; Zero-extend OP5.
1554 (set (match_dup 5)
1555 (ashift:DI (match_dup 5)
1556 (const_int 32)))
1557 (set (match_dup 5)
1558 (lshiftrt:DI (match_dup 5)
1559 (const_int 32)))
1560
1561 ;; Shift OP0 into place.
1562 (set (match_dup 0)
1563 (ashift:DI (match_dup 0)
1564 (const_int 32)))
1565
1566 ;; OR the two halves together
1567 (set (match_dup 0)
1568 (ior:DI (match_dup 0)
1569 (match_dup 5)))]
1570 ""
1571 [(set_attr "type" "imul")
1572 (set_attr "mode" "SI")
1573 (set_attr "length" "24")])
1574
1575(define_insn "*<u>mulsidi3_64bit_parts"
1576 [(set (match_operand:DI 0 "register_operand" "=l")
1577 (sign_extend:DI
1578 (mult:SI (match_operand:SI 2 "register_operand" "d")
1579 (match_operand:SI 3 "register_operand" "d"))))
1580 (set (match_operand:DI 1 "register_operand" "=h")
1581 (ashiftrt:DI
1582 (mult:DI (any_extend:DI (match_dup 2))
1583 (any_extend:DI (match_dup 3)))
1584 (const_int 32)))]
1585 "TARGET_64BIT && !TARGET_FIX_R4000"
1586 "mult<u>\t%2,%3"
1587 [(set_attr "type" "imul")
1588 (set_attr "mode" "SI")])
1589
1590;; Widening multiply with negation.
1591(define_insn "*muls<u>_di"
1592 [(set (match_operand:DI 0 "register_operand" "=x")
1593 (neg:DI
1594 (mult:DI
1595 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1596 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1597 "!TARGET_64BIT && ISA_HAS_MULS"
1598 "muls<u>\t$0,%1,%2"
1599 [(set_attr "type" "imul")
1600 (set_attr "mode" "SI")])
1601
1602(define_insn "*msac<u>_di"
1603 [(set (match_operand:DI 0 "register_operand" "=x")
1604 (minus:DI
1605 (match_operand:DI 3 "register_operand" "0")
1606 (mult:DI
1607 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1608 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1609 "!TARGET_64BIT && ISA_HAS_MSAC"
1610{
1611 if (TARGET_MIPS5500)
1612 return "msub<u>\t%1,%2";
1613 else
1614 return "msac<u>\t$0,%1,%2";
1615}
1616 [(set_attr "type" "imadd")
1617 (set_attr "mode" "SI")])
1618
1619;; _highpart patterns
1620
1621(define_expand "<su>mulsi3_highpart"
1622 [(set (match_operand:SI 0 "register_operand")
1623 (truncate:SI
1624 (lshiftrt:DI
1625 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1626 (any_extend:DI (match_operand:SI 2 "register_operand")))
1627 (const_int 32))))]
1628 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1629{
1630 if (ISA_HAS_MULHI)
1631 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1632 operands[1],
1633 operands[2]));
1634 else
1635 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1636 operands[2]));
1637 DONE;
1638})
1639
1640(define_insn "<su>mulsi3_highpart_internal"
1641 [(set (match_operand:SI 0 "register_operand" "=h")
1642 (truncate:SI
1643 (lshiftrt:DI
1644 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1645 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1646 (const_int 32))))
1647 (clobber (match_scratch:SI 3 "=l"))]
1648 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1649 "mult<u>\t%1,%2"
1650 [(set_attr "type" "imul")
1651 (set_attr "mode" "SI")])
1652
1653(define_insn "<su>mulsi3_highpart_mulhi_internal"
1654 [(set (match_operand:SI 0 "register_operand" "=h,d")
1655 (truncate:SI
1656 (lshiftrt:DI
1657 (mult:DI
1658 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1659 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1660 (const_int 32))))
1661 (clobber (match_scratch:SI 3 "=l,l"))
1662 (clobber (match_scratch:SI 4 "=X,h"))]
1663 "ISA_HAS_MULHI"
1664 "@
1665 mult<u>\t%1,%2
1666 mulhi<u>\t%0,%1,%2"
1667 [(set_attr "type" "imul,imul3")
1668 (set_attr "mode" "SI")])
1669
1670(define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1671 [(set (match_operand:SI 0 "register_operand" "=h,d")
1672 (truncate:SI
1673 (lshiftrt:DI
1674 (neg:DI
1675 (mult:DI
1676 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1677 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1678 (const_int 32))))
1679 (clobber (match_scratch:SI 3 "=l,l"))
1680 (clobber (match_scratch:SI 4 "=X,h"))]
1681 "ISA_HAS_MULHI"
1682 "@
1683 mulshi<u>\t%.,%1,%2
1684 mulshi<u>\t%0,%1,%2"
1685 [(set_attr "type" "imul,imul3")
1686 (set_attr "mode" "SI")])
1687
1688;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1689;; errata MD(0), which says that dmultu does not always produce the
1690;; correct result.
1691(define_insn "<su>muldi3_highpart"
1692 [(set (match_operand:DI 0 "register_operand" "=h")
1693 (truncate:DI
1694 (lshiftrt:TI
1695 (mult:TI
1696 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1697 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1698 (const_int 64))))
1699 (clobber (match_scratch:DI 3 "=l"))]
1700 "TARGET_64BIT && !TARGET_FIX_R4000
1701 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1702 "dmult<u>\t%1,%2"
1703 [(set_attr "type" "imul")
1704 (set_attr "mode" "DI")])
1705
1706;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1707;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1708
1709(define_insn "madsi"
1710 [(set (match_operand:SI 0 "register_operand" "+l")
1711 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1712 (match_operand:SI 2 "register_operand" "d"))
1713 (match_dup 0)))
1714 (clobber (match_scratch:SI 3 "=h"))]
1715 "TARGET_MAD"
1716 "mad\t%1,%2"
1717 [(set_attr "type" "imadd")
1718 (set_attr "mode" "SI")])
1719
1720(define_insn "*<su>mul_acc_di"
1721 [(set (match_operand:DI 0 "register_operand" "=x")
1722 (plus:DI
1723 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1724 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1725 (match_operand:DI 3 "register_operand" "0")))]
1726 "(TARGET_MAD || ISA_HAS_MACC)
1727 && !TARGET_64BIT"
1728{
1729 if (TARGET_MAD)
1730 return "mad<u>\t%1,%2";
1731 else if (TARGET_MIPS5500)
1732 return "madd<u>\t%1,%2";
1733 else
1734 /* See comment in *macc. */
1735 return "%[macc<u>\t%@,%1,%2%]";
1736}
1737 [(set_attr "type" "imadd")
1738 (set_attr "mode" "SI")])
1739
1740;; Floating point multiply accumulate instructions.
1741
1742(define_insn "*madd<mode>"
1743 [(set (match_operand:ANYF 0 "register_operand" "=f")
1744 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1745 (match_operand:ANYF 2 "register_operand" "f"))
1746 (match_operand:ANYF 3 "register_operand" "f")))]
1747 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1748 "madd.<fmt>\t%0,%3,%1,%2"
1749 [(set_attr "type" "fmadd")
1750 (set_attr "mode" "<UNITMODE>")])
1751
1752(define_insn "*msub<mode>"
1753 [(set (match_operand:ANYF 0 "register_operand" "=f")
1754 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1755 (match_operand:ANYF 2 "register_operand" "f"))
1756 (match_operand:ANYF 3 "register_operand" "f")))]
1757 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1758 "msub.<fmt>\t%0,%3,%1,%2"
1759 [(set_attr "type" "fmadd")
1760 (set_attr "mode" "<UNITMODE>")])
1761
1762(define_insn "*nmadd<mode>"
1763 [(set (match_operand:ANYF 0 "register_operand" "=f")
1764 (neg:ANYF (plus:ANYF
1765 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1766 (match_operand:ANYF 2 "register_operand" "f"))
1767 (match_operand:ANYF 3 "register_operand" "f"))))]
1768 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1769 && HONOR_SIGNED_ZEROS (<MODE>mode)
1770 && !HONOR_NANS (<MODE>mode)"
1771 "nmadd.<fmt>\t%0,%3,%1,%2"
1772 [(set_attr "type" "fmadd")
1773 (set_attr "mode" "<UNITMODE>")])
1774
1775(define_insn "*nmadd<mode>_fastmath"
1776 [(set (match_operand:ANYF 0 "register_operand" "=f")
1777 (minus:ANYF
1778 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1779 (match_operand:ANYF 2 "register_operand" "f"))
1780 (match_operand:ANYF 3 "register_operand" "f")))]
1781 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1782 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1783 && !HONOR_NANS (<MODE>mode)"
1784 "nmadd.<fmt>\t%0,%3,%1,%2"
1785 [(set_attr "type" "fmadd")
1786 (set_attr "mode" "<UNITMODE>")])
1787
1788(define_insn "*nmsub<mode>"
1789 [(set (match_operand:ANYF 0 "register_operand" "=f")
1790 (neg:ANYF (minus:ANYF
1791 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1792 (match_operand:ANYF 3 "register_operand" "f"))
1793 (match_operand:ANYF 1 "register_operand" "f"))))]
1794 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1795 && HONOR_SIGNED_ZEROS (<MODE>mode)
1796 && !HONOR_NANS (<MODE>mode)"
1797 "nmsub.<fmt>\t%0,%1,%2,%3"
1798 [(set_attr "type" "fmadd")
1799 (set_attr "mode" "<UNITMODE>")])
1800
1801(define_insn "*nmsub<mode>_fastmath"
1802 [(set (match_operand:ANYF 0 "register_operand" "=f")
1803 (minus:ANYF
1804 (match_operand:ANYF 1 "register_operand" "f")
1805 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1806 (match_operand:ANYF 3 "register_operand" "f"))))]
1807 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1808 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1809 && !HONOR_NANS (<MODE>mode)"
1810 "nmsub.<fmt>\t%0,%1,%2,%3"
1811 [(set_attr "type" "fmadd")
1812 (set_attr "mode" "<UNITMODE>")])
1813
1814;;
1815;; ....................
1816;;
1817;; DIVISION and REMAINDER
1818;;
1819;; ....................
1820;;
1821
1822(define_expand "div<mode>3"
1823 [(set (match_operand:ANYF 0 "register_operand")
1824 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1825 (match_operand:ANYF 2 "register_operand")))]
1826 "<divide_condition>"
1827{
1828 if (const_1_operand (operands[1], <MODE>mode))
1829 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1830 operands[1] = force_reg (<MODE>mode, operands[1]);
1831})
1832
1833;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1834;;
1835;; If an mfc1 or dmfc1 happens to access the floating point register
1836;; file at the same time a long latency operation (div, sqrt, recip,
1837;; sqrt) iterates an intermediate result back through the floating
1838;; point register file bypass, then instead returning the correct
1839;; register value the mfc1 or dmfc1 operation returns the intermediate
1840;; result of the long latency operation.
1841;;
1842;; The workaround is to insert an unconditional 'mov' from/to the
1843;; long latency op destination register.
1844
1845(define_insn "*div<mode>3"
1846 [(set (match_operand:ANYF 0 "register_operand" "=f")
1847 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1848 (match_operand:ANYF 2 "register_operand" "f")))]
1849 "<divide_condition>"
1850{
1851 if (TARGET_FIX_SB1)
1852 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1853 else
1854 return "div.<fmt>\t%0,%1,%2";
1855}
1856 [(set_attr "type" "fdiv")
1857 (set_attr "mode" "<UNITMODE>")
1858 (set (attr "length")
1859 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1860 (const_int 8)
1861 (const_int 4)))])
1862
1863(define_insn "*recip<mode>3"
1864 [(set (match_operand:ANYF 0 "register_operand" "=f")
1865 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1866 (match_operand:ANYF 2 "register_operand" "f")))]
1867 "<recip_condition> && flag_unsafe_math_optimizations"
1868{
1869 if (TARGET_FIX_SB1)
1870 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1871 else
1872 return "recip.<fmt>\t%0,%2";
1873}
1874 [(set_attr "type" "frdiv")
1875 (set_attr "mode" "<UNITMODE>")
1876 (set (attr "length")
1877 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1878 (const_int 8)
1879 (const_int 4)))])
1880
1881;; VR4120 errata MD(A1): signed division instructions do not work correctly
1882;; with negative operands. We use special libgcc functions instead.
1883(define_insn "divmod<mode>4"
1884 [(set (match_operand:GPR 0 "register_operand" "=l")
1885 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1886 (match_operand:GPR 2 "register_operand" "d")))
1887 (set (match_operand:GPR 3 "register_operand" "=h")
1888 (mod:GPR (match_dup 1)
1889 (match_dup 2)))]
1890 "!TARGET_FIX_VR4120"
1891 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1892 [(set_attr "type" "idiv")
1893 (set_attr "mode" "<MODE>")])
1894
1895(define_insn "udivmod<mode>4"
1896 [(set (match_operand:GPR 0 "register_operand" "=l")
1897 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1898 (match_operand:GPR 2 "register_operand" "d")))
1899 (set (match_operand:GPR 3 "register_operand" "=h")
1900 (umod:GPR (match_dup 1)
1901 (match_dup 2)))]
1902 ""
1903 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1904 [(set_attr "type" "idiv")
1905 (set_attr "mode" "<MODE>")])
1906
1907;;
1908;; ....................
1909;;
1910;; SQUARE ROOT
1911;;
1912;; ....................
1913
1914;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1915;; "*div[sd]f3" comment for details).
1916
1917(define_insn "sqrt<mode>2"
1918 [(set (match_operand:ANYF 0 "register_operand" "=f")
1919 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1920 "<sqrt_condition>"
1921{
1922 if (TARGET_FIX_SB1)
1923 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1924 else
1925 return "sqrt.<fmt>\t%0,%1";
1926}
1927 [(set_attr "type" "fsqrt")
1928 (set_attr "mode" "<UNITMODE>")
1929 (set (attr "length")
1930 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1931 (const_int 8)
1932 (const_int 4)))])
1933
1934(define_insn "*rsqrt<mode>a"
1935 [(set (match_operand:ANYF 0 "register_operand" "=f")
1936 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1937 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1938 "<recip_condition> && flag_unsafe_math_optimizations"
1939{
1940 if (TARGET_FIX_SB1)
1941 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1942 else
1943 return "rsqrt.<fmt>\t%0,%2";
1944}
1945 [(set_attr "type" "frsqrt")
1946 (set_attr "mode" "<UNITMODE>")
1947 (set (attr "length")
1948 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1949 (const_int 8)
1950 (const_int 4)))])
1951
1952(define_insn "*rsqrt<mode>b"
1953 [(set (match_operand:ANYF 0 "register_operand" "=f")
1954 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1955 (match_operand:ANYF 2 "register_operand" "f"))))]
1956 "<recip_condition> && flag_unsafe_math_optimizations"
1957{
1958 if (TARGET_FIX_SB1)
1959 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1960 else
1961 return "rsqrt.<fmt>\t%0,%2";
1962}
1963 [(set_attr "type" "frsqrt")
1964 (set_attr "mode" "<UNITMODE>")
1965 (set (attr "length")
1966 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1967 (const_int 8)
1968 (const_int 4)))])
1969
1970;;
1971;; ....................
1972;;
1973;; ABSOLUTE VALUE
1974;;
1975;; ....................
1976
1977;; Do not use the integer abs macro instruction, since that signals an
1978;; exception on -2147483648 (sigh).
1979
1980;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
1981;; invalid; it does not clear their sign bits. We therefore can't use
1982;; abs.fmt if the signs of NaNs matter.
1983
1984(define_insn "abs<mode>2"
1985 [(set (match_operand:ANYF 0 "register_operand" "=f")
1986 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1987 "!HONOR_NANS (<MODE>mode)"
1988 "abs.<fmt>\t%0,%1"
1989 [(set_attr "type" "fabs")
1990 (set_attr "mode" "<UNITMODE>")])
1991
1992;;
1993;; ...................
1994;;
1995;; Count leading zeroes.
1996;;
1997;; ...................
1998;;
1999
2000(define_insn "clz<mode>2"
2001 [(set (match_operand:GPR 0 "register_operand" "=d")
2002 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2003 "ISA_HAS_CLZ_CLO"
2004 "<d>clz\t%0,%1"
2005 [(set_attr "type" "clz")
2006 (set_attr "mode" "<MODE>")])
2007
2008;;
2009;; ....................
2010;;
2011;; NEGATION and ONE'S COMPLEMENT
2012;;
2013;; ....................
2014
2015(define_insn "negsi2"
2016 [(set (match_operand:SI 0 "register_operand" "=d")
2017 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2018 ""
2019{
2020 if (TARGET_MIPS16)
2021 return "neg\t%0,%1";
2022 else
2023 return "subu\t%0,%.,%1";
2024}
2025 [(set_attr "type" "arith")
2026 (set_attr "mode" "SI")])
2027
2028(define_insn "negdi2"
2029 [(set (match_operand:DI 0 "register_operand" "=d")
2030 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2031 "TARGET_64BIT && !TARGET_MIPS16"
2032 "dsubu\t%0,%.,%1"
2033 [(set_attr "type" "arith")
2034 (set_attr "mode" "DI")])
2035
2036;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2037;; invalid; it does not flip their sign bit. We therefore can't use
2038;; neg.fmt if the signs of NaNs matter.
2039
2040(define_insn "neg<mode>2"
2041 [(set (match_operand:ANYF 0 "register_operand" "=f")
2042 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2043 "!HONOR_NANS (<MODE>mode)"
2044 "neg.<fmt>\t%0,%1"
2045 [(set_attr "type" "fneg")
2046 (set_attr "mode" "<UNITMODE>")])
2047
2048(define_insn "one_cmpl<mode>2"
2049 [(set (match_operand:GPR 0 "register_operand" "=d")
2050 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2051 ""
2052{
2053 if (TARGET_MIPS16)
2054 return "not\t%0,%1";
2055 else
2056 return "nor\t%0,%.,%1";
2057}
2058 [(set_attr "type" "arith")
2059 (set_attr "mode" "<MODE>")])
2060
2061;;
2062;; ....................
2063;;
2064;; LOGICAL
2065;;
2066;; ....................
2067;;
2068
2069;; Many of these instructions use trivial define_expands, because we
2070;; want to use a different set of constraints when TARGET_MIPS16.
2071
2072(define_expand "and<mode>3"
2073 [(set (match_operand:GPR 0 "register_operand")
2074 (and:GPR (match_operand:GPR 1 "register_operand")
2075 (match_operand:GPR 2 "uns_arith_operand")))]
2076 ""
2077{
2078 if (TARGET_MIPS16)
2079 operands[2] = force_reg (<MODE>mode, operands[2]);
2080})
2081
2082(define_insn "*and<mode>3"
2083 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2084 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2085 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2086 "!TARGET_MIPS16"
2087 "@
2088 and\t%0,%1,%2
2089 andi\t%0,%1,%x2"
2090 [(set_attr "type" "arith")
2091 (set_attr "mode" "<MODE>")])
2092
2093(define_insn "*and<mode>3_mips16"
2094 [(set (match_operand:GPR 0 "register_operand" "=d")
2095 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2096 (match_operand:GPR 2 "register_operand" "d")))]
2097 "TARGET_MIPS16"
2098 "and\t%0,%2"
2099 [(set_attr "type" "arith")
2100 (set_attr "mode" "<MODE>")])
2101
2102(define_expand "ior<mode>3"
2103 [(set (match_operand:GPR 0 "register_operand")
2104 (ior:GPR (match_operand:GPR 1 "register_operand")
2105 (match_operand:GPR 2 "uns_arith_operand")))]
2106 ""
2107{
2108 if (TARGET_MIPS16)
2109 operands[2] = force_reg (<MODE>mode, operands[2]);
2110})
2111
2112(define_insn "*ior<mode>3"
2113 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2114 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2115 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2116 "!TARGET_MIPS16"
2117 "@
2118 or\t%0,%1,%2
2119 ori\t%0,%1,%x2"
2120 [(set_attr "type" "arith")
2121 (set_attr "mode" "<MODE>")])
2122
2123(define_insn "*ior<mode>3_mips16"
2124 [(set (match_operand:GPR 0 "register_operand" "=d")
2125 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2126 (match_operand:GPR 2 "register_operand" "d")))]
2127 "TARGET_MIPS16"
2128 "or\t%0,%2"
2129 [(set_attr "type" "arith")
2130 (set_attr "mode" "<MODE>")])
2131
2132(define_expand "xor<mode>3"
2133 [(set (match_operand:GPR 0 "register_operand")
2134 (xor:GPR (match_operand:GPR 1 "register_operand")
2135 (match_operand:GPR 2 "uns_arith_operand")))]
2136 ""
2137 "")
2138
2139(define_insn ""
2140 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2141 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2142 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2143 "!TARGET_MIPS16"
2144 "@
2145 xor\t%0,%1,%2
2146 xori\t%0,%1,%x2"
2147 [(set_attr "type" "arith")
2148 (set_attr "mode" "<MODE>")])
2149
2150(define_insn ""
2151 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2152 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2153 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2154 "TARGET_MIPS16"
2155 "@
2156 xor\t%0,%2
2157 cmpi\t%1,%2
2158 cmp\t%1,%2"
2159 [(set_attr "type" "arith")
2160 (set_attr "mode" "<MODE>")
2161 (set_attr_alternative "length"
2162 [(const_int 4)
2163 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2164 (const_int 4)
2165 (const_int 8))
2166 (const_int 4)])])
2167
2168(define_insn "*nor<mode>3"
2169 [(set (match_operand:GPR 0 "register_operand" "=d")
2170 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2171 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2172 "!TARGET_MIPS16"
2173 "nor\t%0,%1,%2"
2174 [(set_attr "type" "arith")
2175 (set_attr "mode" "<MODE>")])
2176
2177;;
2178;; ....................
2179;;
2180;; TRUNCATION
2181;;
2182;; ....................
2183
2184
2185
2186(define_insn "truncdfsf2"
2187 [(set (match_operand:SF 0 "register_operand" "=f")
2188 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2189 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2190 "cvt.s.d\t%0,%1"
2191 [(set_attr "type" "fcvt")
2192 (set_attr "cnv_mode" "D2S")
2193 (set_attr "mode" "SF")])
2194
2195;; Integer truncation patterns. Truncating SImode values to smaller
2196;; modes is a no-op, as it is for most other GCC ports. Truncating
2197;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2198;; need to make sure that the lower 32 bits are properly sign-extended
2199;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2200;; smaller than SImode is equivalent to two separate truncations:
2201;;
2202;; A B
2203;; DI ---> HI == DI ---> SI ---> HI
2204;; DI ---> QI == DI ---> SI ---> QI
2205;;
2206;; Step A needs a real instruction but step B does not.
2207
2208(define_insn "truncdisi2"
2209 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2210 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2211 "TARGET_64BIT"
2212 "@
2213 sll\t%0,%1,0
2214 sw\t%1,%0"
2215 [(set_attr "type" "shift,store")
2216 (set_attr "mode" "SI")
2217 (set_attr "extended_mips16" "yes,*")])
2218
2219(define_insn "truncdihi2"
2220 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2221 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2222 "TARGET_64BIT"
2223 "@
2224 sll\t%0,%1,0
2225 sh\t%1,%0"
2226 [(set_attr "type" "shift,store")
2227 (set_attr "mode" "SI")
2228 (set_attr "extended_mips16" "yes,*")])
2229
2230(define_insn "truncdiqi2"
2231 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2232 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2233 "TARGET_64BIT"
2234 "@
2235 sll\t%0,%1,0
2236 sb\t%1,%0"
2237 [(set_attr "type" "shift,store")
2238 (set_attr "mode" "SI")
2239 (set_attr "extended_mips16" "yes,*")])
2240
2241;; Combiner patterns to optimize shift/truncate combinations.
2242
2243(define_insn ""
2244 [(set (match_operand:SI 0 "register_operand" "=d")
2245 (truncate:SI
2246 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2247 (match_operand:DI 2 "const_arith_operand" ""))))]
2248 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2249 "dsra\t%0,%1,%2"
2250 [(set_attr "type" "shift")
2251 (set_attr "mode" "SI")])
2252
2253(define_insn ""
2254 [(set (match_operand:SI 0 "register_operand" "=d")
2255 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2256 (const_int 32))))]
2257 "TARGET_64BIT && !TARGET_MIPS16"
2258 "dsra\t%0,%1,32"
2259 [(set_attr "type" "shift")
2260 (set_attr "mode" "SI")])
2261
2262
2263;; Combiner patterns for truncate/sign_extend combinations. They use
2264;; the shift/truncate patterns above.
2265
2266(define_insn_and_split ""
2267 [(set (match_operand:SI 0 "register_operand" "=d")
2268 (sign_extend:SI
2269 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2270 "TARGET_64BIT && !TARGET_MIPS16"
2271 "#"
2272 "&& reload_completed"
2273 [(set (match_dup 2)
2274 (ashift:DI (match_dup 1)
2275 (const_int 48)))
2276 (set (match_dup 0)
2277 (truncate:SI (ashiftrt:DI (match_dup 2)
2278 (const_int 48))))]
2279 { operands[2] = gen_lowpart (DImode, operands[0]); })
2280
2281(define_insn_and_split ""
2282 [(set (match_operand:SI 0 "register_operand" "=d")
2283 (sign_extend:SI
2284 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2285 "TARGET_64BIT && !TARGET_MIPS16"
2286 "#"
2287 "&& reload_completed"
2288 [(set (match_dup 2)
2289 (ashift:DI (match_dup 1)
2290 (const_int 56)))
2291 (set (match_dup 0)
2292 (truncate:SI (ashiftrt:DI (match_dup 2)
2293 (const_int 56))))]
2294 { operands[2] = gen_lowpart (DImode, operands[0]); })
2295
2296
2297;; Combiner patterns to optimize truncate/zero_extend combinations.
2298
2299(define_insn ""
2300 [(set (match_operand:SI 0 "register_operand" "=d")
2301 (zero_extend:SI (truncate:HI
2302 (match_operand:DI 1 "register_operand" "d"))))]
2303 "TARGET_64BIT && !TARGET_MIPS16"
2304 "andi\t%0,%1,0xffff"
2305 [(set_attr "type" "arith")
2306 (set_attr "mode" "SI")])
2307
2308(define_insn ""
2309 [(set (match_operand:SI 0 "register_operand" "=d")
2310 (zero_extend:SI (truncate:QI
2311 (match_operand:DI 1 "register_operand" "d"))))]
2312 "TARGET_64BIT && !TARGET_MIPS16"
2313 "andi\t%0,%1,0xff"
2314 [(set_attr "type" "arith")
2315 (set_attr "mode" "SI")])
2316
2317(define_insn ""
2318 [(set (match_operand:HI 0 "register_operand" "=d")
2319 (zero_extend:HI (truncate:QI
2320 (match_operand:DI 1 "register_operand" "d"))))]
2321 "TARGET_64BIT && !TARGET_MIPS16"
2322 "andi\t%0,%1,0xff"
2323 [(set_attr "type" "arith")
2324 (set_attr "mode" "HI")])
2325
2326;;
2327;; ....................
2328;;
2329;; ZERO EXTENSION
2330;;
2331;; ....................
2332
2333;; Extension insns.
2334
2335(define_insn_and_split "zero_extendsidi2"
2336 [(set (match_operand:DI 0 "register_operand" "=d,d")
2337 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2338 "TARGET_64BIT"
2339 "@
2340 #
2341 lwu\t%0,%1"
2342 "&& reload_completed && REG_P (operands[1])"
2343 [(set (match_dup 0)
2344 (ashift:DI (match_dup 1) (const_int 32)))
2345 (set (match_dup 0)
2346 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2347 { operands[1] = gen_lowpart (DImode, operands[1]); }
2348 [(set_attr "type" "multi,load")
2349 (set_attr "mode" "DI")
2350 (set_attr "length" "8,*")])
2351
2352;; Combine is not allowed to convert this insn into a zero_extendsidi2
2353;; because of TRULY_NOOP_TRUNCATION.
2354
2355(define_insn_and_split "*clear_upper32"
2356 [(set (match_operand:DI 0 "register_operand" "=d,d")
2357 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2358 (const_int 4294967295)))]
2359 "TARGET_64BIT"
2360{
2361 if (which_alternative == 0)
2362 return "#";
2363
2364 operands[1] = gen_lowpart (SImode, operands[1]);
2365 return "lwu\t%0,%1";
2366}
2367 "&& reload_completed && REG_P (operands[1])"
2368 [(set (match_dup 0)
2369 (ashift:DI (match_dup 1) (const_int 32)))
2370 (set (match_dup 0)
2371 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2372 ""
2373 [(set_attr "type" "multi,load")
2374 (set_attr "mode" "DI")
2375 (set_attr "length" "8,*")])
2376
2377(define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2378 [(set (match_operand:GPR 0 "register_operand")
2379 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2380 ""
2381{
2382 if (TARGET_MIPS16 && !GENERATE_MIPS16E
2383 && !memory_operand (operands[1], <SHORT:MODE>mode))
2384 {
2385 emit_insn (gen_and<GPR:mode>3 (operands[0],
2386 gen_lowpart (<GPR:MODE>mode, operands[1]),
2387 force_reg (<GPR:MODE>mode,
2388 GEN_INT (<SHORT:mask>))));
2389 DONE;
2390 }
2391})
2392
2393(define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2394 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2395 (zero_extend:GPR
2396 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2397 "!TARGET_MIPS16"
2398 "@
2399 andi\t%0,%1,<SHORT:mask>
2400 l<SHORT:size>u\t%0,%1"
2401 [(set_attr "type" "arith,load")
2402 (set_attr "mode" "<GPR:MODE>")])
2403
2404(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2405 [(set (match_operand:GPR 0 "register_operand" "=d")
2406 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2407 "GENERATE_MIPS16E"
2408 "ze<SHORT:size>\t%0"
2409 [(set_attr "type" "arith")
2410 (set_attr "mode" "<GPR:MODE>")])
2411
2412(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2413 [(set (match_operand:GPR 0 "register_operand" "=d")
2414 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2415 "TARGET_MIPS16"
2416 "l<SHORT:size>u\t%0,%1"
2417 [(set_attr "type" "load")
2418 (set_attr "mode" "<GPR:MODE>")])
2419
2420(define_expand "zero_extendqihi2"
2421 [(set (match_operand:HI 0 "register_operand")
2422 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2423 ""
2424{
2425 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2426 {
2427 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2428 operands[1]));
2429 DONE;
2430 }
2431})
2432
2433(define_insn "*zero_extendqihi2"
2434 [(set (match_operand:HI 0 "register_operand" "=d,d")
2435 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2436 "!TARGET_MIPS16"
2437 "@
2438 andi\t%0,%1,0x00ff
2439 lbu\t%0,%1"
2440 [(set_attr "type" "arith,load")
2441 (set_attr "mode" "HI")])
2442
2443(define_insn "*zero_extendqihi2_mips16"
2444 [(set (match_operand:HI 0 "register_operand" "=d")
2445 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2446 "TARGET_MIPS16"
2447 "lbu\t%0,%1"
2448 [(set_attr "type" "load")
2449 (set_attr "mode" "HI")])
2450
2451;;
2452;; ....................
2453;;
2454;; SIGN EXTENSION
2455;;
2456;; ....................
2457
2458;; Extension insns.
2459;; Those for integer source operand are ordered widest source type first.
2460
2461;; When TARGET_64BIT, all SImode integer registers should already be in
2462;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2463;; therefore get rid of register->register instructions if we constrain
2464;; the source to be in the same register as the destination.
2465;;
2466;; The register alternative has type "arith" so that the pre-reload
2467;; scheduler will treat it as a move. This reflects what happens if
2468;; the register alternative needs a reload.
2469(define_insn_and_split "extendsidi2"
2470 [(set (match_operand:DI 0 "register_operand" "=d,d")
2471 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2472 "TARGET_64BIT"
2473 "@
2474 #
2475 lw\t%0,%1"
2476 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2477 [(const_int 0)]
2478{
2479 emit_note (NOTE_INSN_DELETED);
2480 DONE;
2481}
2482 [(set_attr "type" "arith,load")
2483 (set_attr "mode" "DI")])
2484
2485(define_expand "extend<SHORT:mode><GPR:mode>2"
2486 [(set (match_operand:GPR 0 "register_operand")
2487 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2488 "")
2489
2490(define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2491 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2492 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2493 "GENERATE_MIPS16E"
2494 "@
2495 se<SHORT:size>\t%0
2496 l<SHORT:size>\t%0,%1"
2497 [(set_attr "type" "arith,load")
2498 (set_attr "mode" "<GPR:MODE>")])
2499
2500(define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2501 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2502 (sign_extend:GPR
2503 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2504 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2505 "@
2506 #
2507 l<SHORT:size>\t%0,%1"
2508 "&& reload_completed && REG_P (operands[1])"
2509 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2510 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2511{
2512 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2513 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2514 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2515}
2516 [(set_attr "type" "arith,load")
2517 (set_attr "mode" "<GPR:MODE>")
2518 (set_attr "length" "8,*")])
2519
2520(define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2521 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2522 (sign_extend:GPR
2523 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2524 "ISA_HAS_SEB_SEH"
2525 "@
2526 se<SHORT:size>\t%0,%1
2527 l<SHORT:size>\t%0,%1"
2528 [(set_attr "type" "arith,load")
2529 (set_attr "mode" "<GPR:MODE>")])
2530
2531;; This pattern generates the same code as extendqisi2; split it into
2532;; that form after reload.
2533(define_insn_and_split "extendqihi2"
2534 [(set (match_operand:HI 0 "register_operand" "=d,d")
2535 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2536 ""
2537 "#"
2538 "reload_completed"
2539 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2540 { operands[0] = gen_lowpart (SImode, operands[0]); }
2541 [(set_attr "type" "arith,load")
2542 (set_attr "mode" "SI")
2543 (set_attr "length" "8,*")])
2544
2545(define_insn "extendsfdf2"
2546 [(set (match_operand:DF 0 "register_operand" "=f")
2547 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2548 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2549 "cvt.d.s\t%0,%1"
2550 [(set_attr "type" "fcvt")
2551 (set_attr "cnv_mode" "S2D")
2552 (set_attr "mode" "DF")])
2553
2554;;
2555;; ....................
2556;;
2557;; CONVERSIONS
2558;;
2559;; ....................
2560
2561(define_expand "fix_truncdfsi2"
2562 [(set (match_operand:SI 0 "register_operand")
2563 (fix:SI (match_operand:DF 1 "register_operand")))]
2564 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2565{
2566 if (!ISA_HAS_TRUNC_W)
2567 {
2568 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2569 DONE;
2570 }
2571})
2572
2573(define_insn "fix_truncdfsi2_insn"
2574 [(set (match_operand:SI 0 "register_operand" "=f")
2575 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2576 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2577 "trunc.w.d %0,%1"
2578 [(set_attr "type" "fcvt")
2579 (set_attr "mode" "DF")
2580 (set_attr "cnv_mode" "D2I")
2581 (set_attr "length" "4")])
2582
2583(define_insn "fix_truncdfsi2_macro"
2584 [(set (match_operand:SI 0 "register_operand" "=f")
2585 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2586 (clobber (match_scratch:DF 2 "=d"))]
2587 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2588{
2589 if (set_nomacro)
2590 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2591 else
2592 return "trunc.w.d %0,%1,%2";
2593}
2594 [(set_attr "type" "fcvt")
2595 (set_attr "mode" "DF")
2596 (set_attr "cnv_mode" "D2I")
2597 (set_attr "length" "36")])
2598
2599(define_expand "fix_truncsfsi2"
2600 [(set (match_operand:SI 0 "register_operand")
2601 (fix:SI (match_operand:SF 1 "register_operand")))]
2602 "TARGET_HARD_FLOAT"
2603{
2604 if (!ISA_HAS_TRUNC_W)
2605 {
2606 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2607 DONE;
2608 }
2609})
2610
2611(define_insn "fix_truncsfsi2_insn"
2612 [(set (match_operand:SI 0 "register_operand" "=f")
2613 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2614 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2615 "trunc.w.s %0,%1"
2616 [(set_attr "type" "fcvt")
2617 (set_attr "mode" "SF")
2618 (set_attr "cnv_mode" "S2I")
2619 (set_attr "length" "4")])
2620
2621(define_insn "fix_truncsfsi2_macro"
2622 [(set (match_operand:SI 0 "register_operand" "=f")
2623 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2624 (clobber (match_scratch:SF 2 "=d"))]
2625 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2626{
2627 if (set_nomacro)
2628 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2629 else
2630 return "trunc.w.s %0,%1,%2";
2631}
2632 [(set_attr "type" "fcvt")
2633 (set_attr "mode" "SF")
2634 (set_attr "cnv_mode" "S2I")
2635 (set_attr "length" "36")])
2636
2637
2638(define_insn "fix_truncdfdi2"
2639 [(set (match_operand:DI 0 "register_operand" "=f")
2640 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2641 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2642 "trunc.l.d %0,%1"
2643 [(set_attr "type" "fcvt")
2644 (set_attr "mode" "DF")
2645 (set_attr "cnv_mode" "D2I")
2646 (set_attr "length" "4")])
2647
2648
2649(define_insn "fix_truncsfdi2"
2650 [(set (match_operand:DI 0 "register_operand" "=f")
2651 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2652 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2653 "trunc.l.s %0,%1"
2654 [(set_attr "type" "fcvt")
2655 (set_attr "mode" "SF")
2656 (set_attr "cnv_mode" "S2I")
2657 (set_attr "length" "4")])
2658
2659
2660(define_insn "floatsidf2"
2661 [(set (match_operand:DF 0 "register_operand" "=f")
2662 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2663 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2664 "cvt.d.w\t%0,%1"
2665 [(set_attr "type" "fcvt")
2666 (set_attr "mode" "DF")
2667 (set_attr "cnv_mode" "I2D")
2668 (set_attr "length" "4")])
2669
2670
2671(define_insn "floatdidf2"
2672 [(set (match_operand:DF 0 "register_operand" "=f")
2673 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2674 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2675 "cvt.d.l\t%0,%1"
2676 [(set_attr "type" "fcvt")
2677 (set_attr "mode" "DF")
2678 (set_attr "cnv_mode" "I2D")
2679 (set_attr "length" "4")])
2680
2681
2682(define_insn "floatsisf2"
2683 [(set (match_operand:SF 0 "register_operand" "=f")
2684 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2685 "TARGET_HARD_FLOAT"
2686 "cvt.s.w\t%0,%1"
2687 [(set_attr "type" "fcvt")
2688 (set_attr "mode" "SF")
2689 (set_attr "cnv_mode" "I2S")
2690 (set_attr "length" "4")])
2691
2692
2693(define_insn "floatdisf2"
2694 [(set (match_operand:SF 0 "register_operand" "=f")
2695 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2696 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2697 "cvt.s.l\t%0,%1"
2698 [(set_attr "type" "fcvt")
2699 (set_attr "mode" "SF")
2700 (set_attr "cnv_mode" "I2S")
2701 (set_attr "length" "4")])
2702
2703
2704(define_expand "fixuns_truncdfsi2"
2705 [(set (match_operand:SI 0 "register_operand")
2706 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2707 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2708{
2709 rtx reg1 = gen_reg_rtx (DFmode);
2710 rtx reg2 = gen_reg_rtx (DFmode);
2711 rtx reg3 = gen_reg_rtx (SImode);
2712 rtx label1 = gen_label_rtx ();
2713 rtx label2 = gen_label_rtx ();
2714 REAL_VALUE_TYPE offset;
2715
2716 real_2expN (&offset, 31);
2717
2718 if (reg1) /* Turn off complaints about unreached code. */
2719 {
2720 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2721 do_pending_stack_adjust ();
2722
2723 emit_insn (gen_cmpdf (operands[1], reg1));
2724 emit_jump_insn (gen_bge (label1));
2725
2726 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2727 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2728 gen_rtx_LABEL_REF (VOIDmode, label2)));
2729 emit_barrier ();
2730
2731 emit_label (label1);
2732 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2733 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2734 (BITMASK_HIGH, SImode)));
2735
2736 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2737 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2738
2739 emit_label (label2);
2740
2741 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2742 fields, and can't be used for REG_NOTES anyway). */
2743 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2744 DONE;
2745 }
2746})
2747
2748
2749(define_expand "fixuns_truncdfdi2"
2750 [(set (match_operand:DI 0 "register_operand")
2751 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2752 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2753{
2754 rtx reg1 = gen_reg_rtx (DFmode);
2755 rtx reg2 = gen_reg_rtx (DFmode);
2756 rtx reg3 = gen_reg_rtx (DImode);
2757 rtx label1 = gen_label_rtx ();
2758 rtx label2 = gen_label_rtx ();
2759 REAL_VALUE_TYPE offset;
2760
2761 real_2expN (&offset, 63);
2762
2763 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2764 do_pending_stack_adjust ();
2765
2766 emit_insn (gen_cmpdf (operands[1], reg1));
2767 emit_jump_insn (gen_bge (label1));
2768
2769 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2770 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2771 gen_rtx_LABEL_REF (VOIDmode, label2)));
2772 emit_barrier ();
2773
2774 emit_label (label1);
2775 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2776 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2777 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2778
2779 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2780 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2781
2782 emit_label (label2);
2783
2784 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2785 fields, and can't be used for REG_NOTES anyway). */
2786 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2787 DONE;
2788})
2789
2790
2791(define_expand "fixuns_truncsfsi2"
2792 [(set (match_operand:SI 0 "register_operand")
2793 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2794 "TARGET_HARD_FLOAT"
2795{
2796 rtx reg1 = gen_reg_rtx (SFmode);
2797 rtx reg2 = gen_reg_rtx (SFmode);
2798 rtx reg3 = gen_reg_rtx (SImode);
2799 rtx label1 = gen_label_rtx ();
2800 rtx label2 = gen_label_rtx ();
2801 REAL_VALUE_TYPE offset;
2802
2803 real_2expN (&offset, 31);
2804
2805 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2806 do_pending_stack_adjust ();
2807
2808 emit_insn (gen_cmpsf (operands[1], reg1));
2809 emit_jump_insn (gen_bge (label1));
2810
2811 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2812 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2813 gen_rtx_LABEL_REF (VOIDmode, label2)));
2814 emit_barrier ();
2815
2816 emit_label (label1);
2817 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2818 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2819 (BITMASK_HIGH, SImode)));
2820
2821 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2822 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2823
2824 emit_label (label2);
2825
2826 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2827 fields, and can't be used for REG_NOTES anyway). */
2828 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2829 DONE;
2830})
2831
2832
2833(define_expand "fixuns_truncsfdi2"
2834 [(set (match_operand:DI 0 "register_operand")
2835 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2836 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2837{
2838 rtx reg1 = gen_reg_rtx (SFmode);
2839 rtx reg2 = gen_reg_rtx (SFmode);
2840 rtx reg3 = gen_reg_rtx (DImode);
2841 rtx label1 = gen_label_rtx ();
2842 rtx label2 = gen_label_rtx ();
2843 REAL_VALUE_TYPE offset;
2844
2845 real_2expN (&offset, 63);
2846
2847 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2848 do_pending_stack_adjust ();
2849
2850 emit_insn (gen_cmpsf (operands[1], reg1));
2851 emit_jump_insn (gen_bge (label1));
2852
2853 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2854 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2855 gen_rtx_LABEL_REF (VOIDmode, label2)));
2856 emit_barrier ();
2857
2858 emit_label (label1);
2859 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2860 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2861 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2862
2863 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2864 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2865
2866 emit_label (label2);
2867
2868 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2869 fields, and can't be used for REG_NOTES anyway). */
2870 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2871 DONE;
2872})
2873
2874;;
2875;; ....................
2876;;
2877;; DATA MOVEMENT
2878;;
2879;; ....................
2880
2881;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2882
2883(define_expand "extv"
2884 [(set (match_operand 0 "register_operand")
2885 (sign_extract (match_operand:QI 1 "memory_operand")
2886 (match_operand 2 "immediate_operand")
2887 (match_operand 3 "immediate_operand")))]
2888 "!TARGET_MIPS16"
2889{
2890 if (mips_expand_unaligned_load (operands[0], operands[1],
2891 INTVAL (operands[2]),
2892 INTVAL (operands[3])))
2893 DONE;
2894 else
2895 FAIL;
2896})
2897
2898(define_expand "extzv"
2899 [(set (match_operand 0 "register_operand")
2900 (zero_extract (match_operand 1 "nonimmediate_operand")
2901 (match_operand 2 "immediate_operand")
2902 (match_operand 3 "immediate_operand")))]
2903 "!TARGET_MIPS16"
2904{
2905 if (mips_expand_unaligned_load (operands[0], operands[1],
2906 INTVAL (operands[2]),
2907 INTVAL (operands[3])))
2908 DONE;
2909 else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
2910 {
2911 if (GET_MODE (operands[0]) == DImode)
2912 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
2913 operands[3]));
2914 else
2915 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
2916 operands[3]));
2917 DONE;
2918 }
2919 else
2920 FAIL;
2921})
2922
2923(define_insn "extzv<mode>"
2924 [(set (match_operand:GPR 0 "register_operand" "=d")
2925 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
2926 (match_operand:SI 2 "immediate_operand" "I")
2927 (match_operand:SI 3 "immediate_operand" "I")))]
2928 "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
2929 "<d>ext\t%0,%1,%3,%2"
2930 [(set_attr "type" "arith")
2931 (set_attr "mode" "<MODE>")])
2932
2933
2934(define_expand "insv"
2935 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2936 (match_operand 1 "immediate_operand")
2937 (match_operand 2 "immediate_operand"))
2938 (match_operand 3 "reg_or_0_operand"))]
2939 "!TARGET_MIPS16"
2940{
2941 if (mips_expand_unaligned_store (operands[0], operands[3],
2942 INTVAL (operands[1]),
2943 INTVAL (operands[2])))
2944 DONE;
2945 else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
2946 {
2947 if (GET_MODE (operands[0]) == DImode)
2948 emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
2949 operands[3]));
2950 else
2951 emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
2952 operands[3]));
2953 DONE;
2954 }
2955 else
2956 FAIL;
2957})
2958
2959(define_insn "insv<mode>"
2960 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
2961 (match_operand:SI 1 "immediate_operand" "I")
2962 (match_operand:SI 2 "immediate_operand" "I"))
2963 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
2964 "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
2965 "<d>ins\t%0,%z3,%2,%1"
2966 [(set_attr "type" "arith")
2967 (set_attr "mode" "<MODE>")])
2968
2969;; Unaligned word moves generated by the bit field patterns.
2970;;
2971;; As far as the rtl is concerned, both the left-part and right-part
2972;; instructions can access the whole field. However, the real operand
2973;; refers to just the first or the last byte (depending on endianness).
2974;; We therefore use two memory operands to each instruction, one to
2975;; describe the rtl effect and one to use in the assembly output.
2976;;
2977;; Operands 0 and 1 are the rtl-level target and source respectively.
2978;; This allows us to use the standard length calculations for the "load"
2979;; and "store" type attributes.
2980
2981(define_insn "mov_<load>l"
2982 [(set (match_operand:GPR 0 "register_operand" "=d")
2983 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2984 (match_operand:QI 2 "memory_operand" "m")]
2985 UNSPEC_LOAD_LEFT))]
2986 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
2987 "<load>l\t%0,%2"
2988 [(set_attr "type" "load")
2989 (set_attr "mode" "<MODE>")])
2990
2991(define_insn "mov_<load>r"
2992 [(set (match_operand:GPR 0 "register_operand" "=d")
2993 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2994 (match_operand:QI 2 "memory_operand" "m")
2995 (match_operand:GPR 3 "register_operand" "0")]
2996 UNSPEC_LOAD_RIGHT))]
2997 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
2998 "<load>r\t%0,%2"
2999 [(set_attr "type" "load")
3000 (set_attr "mode" "<MODE>")])
3001
3002(define_insn "mov_<store>l"
3003 [(set (match_operand:BLK 0 "memory_operand" "=m")
3004 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3005 (match_operand:QI 2 "memory_operand" "m")]
3006 UNSPEC_STORE_LEFT))]
3007 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3008 "<store>l\t%z1,%2"
3009 [(set_attr "type" "store")
3010 (set_attr "mode" "<MODE>")])
3011
3012(define_insn "mov_<store>r"
3013 [(set (match_operand:BLK 0 "memory_operand" "+m")
3014 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3015 (match_operand:QI 2 "memory_operand" "m")
3016 (match_dup 0)]
3017 UNSPEC_STORE_RIGHT))]
3018 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3019 "<store>r\t%z1,%2"
3020 [(set_attr "type" "store")
3021 (set_attr "mode" "<MODE>")])
3022
3023;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3024;; The required value is:
3025;;
3026;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3027;;
3028;; which translates to:
3029;;
3030;; lui op0,%highest(op1)
3031;; daddiu op0,op0,%higher(op1)
3032;; dsll op0,op0,16
3033;; daddiu op0,op0,%hi(op1)
3034;; dsll op0,op0,16
3035;;
3036;; The split is deferred until after flow2 to allow the peephole2 below
3037;; to take effect.
3038(define_insn_and_split "*lea_high64"
3039 [(set (match_operand:DI 0 "register_operand" "=d")
3040 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3041 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3042 "#"
3043 "&& flow2_completed"
3044 [(set (match_dup 0) (high:DI (match_dup 2)))
3045 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3046 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3047 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3048 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3049{
3050 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3051 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3052}
3053 [(set_attr "length" "20")])
3054
3055;; Use a scratch register to reduce the latency of the above pattern
3056;; on superscalar machines. The optimized sequence is:
3057;;
3058;; lui op1,%highest(op2)
3059;; lui op0,%hi(op2)
3060;; daddiu op1,op1,%higher(op2)
3061;; dsll32 op1,op1,0
3062;; daddu op1,op1,op0
3063(define_peephole2
3064 [(set (match_operand:DI 1 "register_operand")
3065 (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3066 (match_scratch:DI 0 "d")]
3067 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3068 [(set (match_dup 1) (high:DI (match_dup 3)))
3069 (set (match_dup 0) (high:DI (match_dup 4)))
3070 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3071 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3072 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3073{
3074 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3075 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3076})
3077
3078;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3079;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3080;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3081;; used once. We can then use the sequence:
3082;;
3083;; lui op0,%highest(op1)
3084;; lui op2,%hi(op1)
3085;; daddiu op0,op0,%higher(op1)
3086;; daddiu op2,op2,%lo(op1)
3087;; dsll32 op0,op0,0
3088;; daddu op0,op0,op2
3089;;
3090;; which takes 4 cycles on most superscalar targets.
3091(define_insn_and_split "*lea64"
3092 [(set (match_operand:DI 0 "register_operand" "=d")
3093 (match_operand:DI 1 "general_symbolic_operand" ""))
3094 (clobber (match_scratch:DI 2 "=&d"))]
3095 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3096 "#"
3097 "&& reload_completed"
3098 [(set (match_dup 0) (high:DI (match_dup 3)))
3099 (set (match_dup 2) (high:DI (match_dup 4)))
3100 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3101 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3102 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3103 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3104{
3105 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3106 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3107}
3108 [(set_attr "length" "24")])
3109
3110;; Insns to fetch a global symbol from a big GOT.
3111
3112(define_insn_and_split "*xgot_hi<mode>"
3113 [(set (match_operand:P 0 "register_operand" "=d")
3114 (high:P (match_operand:P 1 "global_got_operand" "")))]
3115 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3116 "#"
3117 "&& reload_completed"
3118 [(set (match_dup 0) (high:P (match_dup 2)))
3119 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3120{
3121 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3122 operands[3] = pic_offset_table_rtx;
3123}
3124 [(set_attr "got" "xgot_high")
3125 (set_attr "mode" "<MODE>")])
3126
3127(define_insn_and_split "*xgot_lo<mode>"
3128 [(set (match_operand:P 0 "register_operand" "=d")
3129 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3130 (match_operand:P 2 "global_got_operand" "")))]
3131 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3132 "#"
3133 "&& reload_completed"
3134 [(set (match_dup 0)
3135 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3136 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3137 [(set_attr "got" "load")
3138 (set_attr "mode" "<MODE>")])
3139
3140;; Insns to fetch a global symbol from a normal GOT.
3141
3142(define_insn_and_split "*got_disp<mode>"
3143 [(set (match_operand:P 0 "register_operand" "=d")
3144 (match_operand:P 1 "global_got_operand" ""))]
3145 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3146 "#"
3147 "&& reload_completed"
3148 [(set (match_dup 0)
3149 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3150{
3151 operands[2] = pic_offset_table_rtx;
3152 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3153}
3154 [(set_attr "got" "load")
3155 (set_attr "mode" "<MODE>")])
3156
3157;; Insns for loading the high part of a local symbol.
3158
3159(define_insn_and_split "*got_page<mode>"
3160 [(set (match_operand:P 0 "register_operand" "=d")
3161 (high:P (match_operand:P 1 "local_got_operand" "")))]
3162 "TARGET_EXPLICIT_RELOCS"
3163 "#"
3164 "&& reload_completed"
3165 [(set (match_dup 0)
3166 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3167{
3168 operands[2] = pic_offset_table_rtx;
3169 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3170}
3171 [(set_attr "got" "load")
3172 (set_attr "mode" "<MODE>")])
3173
3174;; Lower-level instructions for loading an address from the GOT.
3175;; We could use MEMs, but an unspec gives more optimization
3176;; opportunities.
3177
3178(define_insn "load_got<mode>"
3179 [(set (match_operand:P 0 "register_operand" "=d")
3180 (unspec:P [(match_operand:P 1 "register_operand" "d")
3181 (match_operand:P 2 "immediate_operand" "")]
3182 UNSPEC_LOAD_GOT))]
3183 ""
3184 "<load>\t%0,%R2(%1)"
3185 [(set_attr "type" "load")
3186 (set_attr "mode" "<MODE>")
3187 (set_attr "length" "4")])
3188
3189;; Instructions for adding the low 16 bits of an address to a register.
3190;; Operand 2 is the address: print_operand works out which relocation
3191;; should be applied.
3192
3193(define_insn "*low<mode>"
3194 [(set (match_operand:P 0 "register_operand" "=d")
3195 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3196 (match_operand:P 2 "immediate_operand" "")))]
3197 "!TARGET_MIPS16"
3198 "<d>addiu\t%0,%1,%R2"
3199 [(set_attr "type" "arith")
3200 (set_attr "mode" "<MODE>")])
3201
3202(define_insn "*low<mode>_mips16"
3203 [(set (match_operand:P 0 "register_operand" "=d")
3204 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3205 (match_operand:P 2 "immediate_operand" "")))]
3206 "TARGET_MIPS16"
3207 "<d>addiu\t%0,%R2"
3208 [(set_attr "type" "arith")
3209 (set_attr "mode" "<MODE>")
3210 (set_attr "length" "8")])
3211
3212;; Allow combine to split complex const_int load sequences, using operand 2
3213;; to store the intermediate results. See move_operand for details.
3214(define_split
3215 [(set (match_operand:GPR 0 "register_operand")
3216 (match_operand:GPR 1 "splittable_const_int_operand"))
3217 (clobber (match_operand:GPR 2 "register_operand"))]
3218 ""
3219 [(const_int 0)]
3220{
3221 mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3222 DONE;
3223})
3224
3225;; Likewise, for symbolic operands.
3226(define_split
3227 [(set (match_operand:P 0 "register_operand")
3228 (match_operand:P 1 "splittable_symbolic_operand"))
3229 (clobber (match_operand:P 2 "register_operand"))]
3230 ""
3231 [(set (match_dup 0) (match_dup 1))]
3232 { operands[1] = mips_split_symbol (operands[2], operands[1]); })
3233
3234;; 64-bit integer moves
3235
3236;; Unlike most other insns, the move insns can't be split with
3237;; different predicates, because register spilling and other parts of
3238;; the compiler, have memoized the insn number already.
3239
3240(define_expand "movdi"
3241 [(set (match_operand:DI 0 "")
3242 (match_operand:DI 1 ""))]
3243 ""
3244{
3245 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3246 DONE;
3247})
3248
3249;; For mips16, we need a special case to handle storing $31 into
3250;; memory, since we don't have a constraint to match $31. This
3251;; instruction can be generated by save_restore_insns.
3252
3253(define_insn "*mov<mode>_ra"
3254 [(set (match_operand:GPR 0 "stack_operand" "=m")
3255 (reg:GPR 31))]
3256 "TARGET_MIPS16"
3257 "<store>\t$31,%0"
3258 [(set_attr "type" "store")
3259 (set_attr "mode" "<MODE>")])
3260
3261(define_insn "*movdi_32bit"
3262 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3263 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3264 "!TARGET_64BIT && !TARGET_MIPS16
3265 && (register_operand (operands[0], DImode)
3266 || reg_or_0_operand (operands[1], DImode))"
3267 { return mips_output_move (operands[0], operands[1]); }
3268 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3269 (set_attr "mode" "DI")
3270 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3271
3272(define_insn "*movdi_32bit_mips16"
3273 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3274 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3275 "!TARGET_64BIT && TARGET_MIPS16
3276 && (register_operand (operands[0], DImode)
3277 || register_operand (operands[1], DImode))"
3278 { return mips_output_move (operands[0], operands[1]); }
3279 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
3280 (set_attr "mode" "DI")
3281 (set_attr "length" "8,8,8,8,12,*,*,8")])
3282
3283(define_insn "*movdi_64bit"
3284 [(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")
3285 (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"))]
3286 "TARGET_64BIT && !TARGET_MIPS16
3287 && (register_operand (operands[0], DImode)
3288 || reg_or_0_operand (operands[1], DImode))"
3289 { return mips_output_move (operands[0], operands[1]); }
3290 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3291 (set_attr "mode" "DI")
3292 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3293
3294(define_insn "*movdi_64bit_mips16"
3295 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3296 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3297 "TARGET_64BIT && TARGET_MIPS16
3298 && (register_operand (operands[0], DImode)
3299 || register_operand (operands[1], DImode))"
3300 { return mips_output_move (operands[0], operands[1]); }
3301 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3302 (set_attr "mode" "DI")
3303 (set_attr_alternative "length"
3304 [(const_int 4)
3305 (const_int 4)
3306 (const_int 4)
3307 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3308 (const_int 4)
3309 (const_int 8))
3310 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3311 (const_int 8)
3312 (const_int 12))
3313 (const_string "*")
3314 (const_string "*")
3315 (const_string "*")])])
3316
3317
3318;; On the mips16, we can split ld $r,N($r) into an add and a load,
3319;; when the original load is a 4 byte instruction but the add and the
3320;; load are 2 2 byte instructions.
3321
3322(define_split
3323 [(set (match_operand:DI 0 "register_operand")
3324 (mem:DI (plus:DI (match_dup 0)
3325 (match_operand:DI 1 "const_int_operand"))))]
3326 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3327 && !TARGET_DEBUG_D_MODE
3328 && REG_P (operands[0])
3329 && M16_REG_P (REGNO (operands[0]))
3330 && GET_CODE (operands[1]) == CONST_INT
3331 && ((INTVAL (operands[1]) < 0
3332 && INTVAL (operands[1]) >= -0x10)
3333 || (INTVAL (operands[1]) >= 32 * 8
3334 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3335 || (INTVAL (operands[1]) >= 0
3336 && INTVAL (operands[1]) < 32 * 8
3337 && (INTVAL (operands[1]) & 7) != 0))"
3338 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3339 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3340{
3341 HOST_WIDE_INT val = INTVAL (operands[1]);
3342
3343 if (val < 0)
3344 operands[2] = const0_rtx;
3345 else if (val >= 32 * 8)
3346 {
3347 int off = val & 7;
3348
3349 operands[1] = GEN_INT (0x8 + off);
3350 operands[2] = GEN_INT (val - off - 0x8);
3351 }
3352 else
3353 {
3354 int off = val & 7;
3355
3356 operands[1] = GEN_INT (off);
3357 operands[2] = GEN_INT (val - off);
3358 }
3359})
3360
3361;; 32-bit Integer moves
3362
3363;; Unlike most other insns, the move insns can't be split with
3364;; different predicates, because register spilling and other parts of
3365;; the compiler, have memoized the insn number already.
3366
3367(define_expand "movsi"
3368 [(set (match_operand:SI 0 "")
3369 (match_operand:SI 1 ""))]
3370 ""
3371{
3372 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3373 DONE;
3374})
3375
3376;; The difference between these two is whether or not ints are allowed
3377;; in FP registers (off by default, use -mdebugh to enable).
3378
3379(define_insn "*movsi_internal"
3380 [(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")
3381 (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"))]
3382 "!TARGET_MIPS16
3383 && (register_operand (operands[0], SImode)
3384 || reg_or_0_operand (operands[1], SImode))"
3385 { return mips_output_move (operands[0], operands[1]); }
3386 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
3387 (set_attr "mode" "SI")
3388 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3389
3390(define_insn "*movsi_mips16"
3391 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3392 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3393 "TARGET_MIPS16
3394 && (register_operand (operands[0], SImode)
3395 || register_operand (operands[1], SImode))"
3396 { return mips_output_move (operands[0], operands[1]); }
3397 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3398 (set_attr "mode" "SI")
3399 (set_attr_alternative "length"
3400 [(const_int 4)
3401 (const_int 4)
3402 (const_int 4)
3403 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3404 (const_int 4)
3405 (const_int 8))
3406 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3407 (const_int 8)
3408 (const_int 12))
3409 (const_string "*")
3410 (const_string "*")
3411 (const_string "*")])])
3412
3413;; On the mips16, we can split lw $r,N($r) into an add and a load,
3414;; when the original load is a 4 byte instruction but the add and the
3415;; load are 2 2 byte instructions.
3416
3417(define_split
3418 [(set (match_operand:SI 0 "register_operand")
3419 (mem:SI (plus:SI (match_dup 0)
3420 (match_operand:SI 1 "const_int_operand"))))]
3421 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3422 && REG_P (operands[0])
3423 && M16_REG_P (REGNO (operands[0]))
3424 && GET_CODE (operands[1]) == CONST_INT
3425 && ((INTVAL (operands[1]) < 0
3426 && INTVAL (operands[1]) >= -0x80)
3427 || (INTVAL (operands[1]) >= 32 * 4
3428 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3429 || (INTVAL (operands[1]) >= 0
3430 && INTVAL (operands[1]) < 32 * 4
3431 && (INTVAL (operands[1]) & 3) != 0))"
3432 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3433 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3434{
3435 HOST_WIDE_INT val = INTVAL (operands[1]);
3436
3437 if (val < 0)
3438 operands[2] = const0_rtx;
3439 else if (val >= 32 * 4)
3440 {
3441 int off = val & 3;
3442
3443 operands[1] = GEN_INT (0x7c + off);
3444 operands[2] = GEN_INT (val - off - 0x7c);
3445 }
3446 else
3447 {
3448 int off = val & 3;
3449
3450 operands[1] = GEN_INT (off);
3451 operands[2] = GEN_INT (val - off);
3452 }
3453})
3454
3455;; On the mips16, we can split a load of certain constants into a load
3456;; and an add. This turns a 4 byte instruction into 2 2 byte
3457;; instructions.
3458
3459(define_split
3460 [(set (match_operand:SI 0 "register_operand")
3461 (match_operand:SI 1 "const_int_operand"))]
3462 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3463 && REG_P (operands[0])
3464 && M16_REG_P (REGNO (operands[0]))
3465 && GET_CODE (operands[1]) == CONST_INT
3466 && INTVAL (operands[1]) >= 0x100
3467 && INTVAL (operands[1]) <= 0xff + 0x7f"
3468 [(set (match_dup 0) (match_dup 1))
3469 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3470{
3471 int val = INTVAL (operands[1]);
3472
3473 operands[1] = GEN_INT (0xff);
3474 operands[2] = GEN_INT (val - 0xff);
3475})
3476
3477;; This insn handles moving CCmode values. It's really just a
3478;; slightly simplified copy of movsi_internal2, with additional cases
3479;; to move a condition register to a general register and to move
3480;; between the general registers and the floating point registers.
3481
3482(define_insn "movcc"
3483 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3484 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3485 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3486 { return mips_output_move (operands[0], operands[1]); }
3487 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3488 (set_attr "mode" "SI")
3489 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3490
3491;; Reload condition code registers. reload_incc and reload_outcc
3492;; both handle moves from arbitrary operands into condition code
3493;; registers. reload_incc handles the more common case in which
3494;; a source operand is constrained to be in a condition-code
3495;; register, but has not been allocated to one.
3496;;
3497;; Sometimes, such as in movcc, we have a CCmode destination whose
3498;; constraints do not include 'z'. reload_outcc handles the case
3499;; when such an operand is allocated to a condition-code register.
3500;;
3501;; Note that reloads from a condition code register to some
3502;; other location can be done using ordinary moves. Moving
3503;; into a GPR takes a single movcc, moving elsewhere takes
3504;; two. We can leave these cases to the generic reload code.
3505(define_expand "reload_incc"
3506 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3507 (match_operand:CC 1 "general_operand" ""))
3508 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3509 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3510{
3511 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3512 DONE;
3513})
3514
3515(define_expand "reload_outcc"
3516 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3517 (match_operand:CC 1 "register_operand" ""))
3518 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3519 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3520{
3521 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3522 DONE;
3523})
3524
3525;; MIPS4 supports loading and storing a floating point register from
3526;; the sum of two general registers. We use two versions for each of
3527;; these four instructions: one where the two general registers are
3528;; SImode, and one where they are DImode. This is because general
3529;; registers will be in SImode when they hold 32 bit values, but,
3530;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3531;; instructions will still work correctly.
3532
3533;; ??? Perhaps it would be better to support these instructions by
3534;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3535;; these instructions can only be used to load and store floating
3536;; point registers, that would probably cause trouble in reload.
3537
3538(define_insn "*<ANYF:loadx>_<P:mode>"
3539 [(set (match_operand:ANYF 0 "register_operand" "=f")
3540 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3541 (match_operand:P 2 "register_operand" "d"))))]
3542 "ISA_HAS_FP4"
3543 "<ANYF:loadx>\t%0,%1(%2)"
3544 [(set_attr "type" "fpidxload")
3545 (set_attr "mode" "<ANYF:UNITMODE>")])
3546
3547(define_insn "*<ANYF:storex>_<P:mode>"
3548 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3549 (match_operand:P 2 "register_operand" "d")))
3550 (match_operand:ANYF 0 "register_operand" "f"))]
3551 "ISA_HAS_FP4"
3552 "<ANYF:storex>\t%0,%1(%2)"
3553 [(set_attr "type" "fpidxstore")
3554 (set_attr "mode" "<ANYF:UNITMODE>")])
3555
3556;; 16-bit Integer moves
3557
3558;; Unlike most other insns, the move insns can't be split with
3559;; different predicates, because register spilling and other parts of
3560;; the compiler, have memoized the insn number already.
3561;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3562
3563(define_expand "movhi"
3564 [(set (match_operand:HI 0 "")
3565 (match_operand:HI 1 ""))]
3566 ""
3567{
3568 if (mips_legitimize_move (HImode, operands[0], operands[1]))
3569 DONE;
3570})
3571
3572(define_insn "*movhi_internal"
3573 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3574 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3575 "!TARGET_MIPS16
3576 && (register_operand (operands[0], HImode)
3577 || reg_or_0_operand (operands[1], HImode))"
3578 "@
3579 move\t%0,%1
3580 li\t%0,%1
3581 lhu\t%0,%1
3582 sh\t%z1,%0
3583 mfc1\t%0,%1
3584 mtc1\t%1,%0
3585 mov.s\t%0,%1
3586 mt%0\t%1"
3587 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3588 (set_attr "mode" "HI")
3589 (set_attr "length" "4,4,*,*,4,4,4,4")])
3590
3591(define_insn "*movhi_mips16"
3592 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3593 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
3594 "TARGET_MIPS16
3595 && (register_operand (operands[0], HImode)
3596 || register_operand (operands[1], HImode))"
3597 "@
3598 move\t%0,%1
3599 move\t%0,%1
3600 move\t%0,%1
3601 li\t%0,%1
3602 #
3603 lhu\t%0,%1
3604 sh\t%1,%0"
3605 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3606 (set_attr "mode" "HI")
3607 (set_attr_alternative "length"
3608 [(const_int 4)
3609 (const_int 4)
3610 (const_int 4)
3611 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3612 (const_int 4)
3613 (const_int 8))
3614 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3615 (const_int 8)
3616 (const_int 12))
3617 (const_string "*")
3618 (const_string "*")])])
3619
3620
3621;; On the mips16, we can split lh $r,N($r) into an add and a load,
3622;; when the original load is a 4 byte instruction but the add and the
3623;; load are 2 2 byte instructions.
3624
3625(define_split
3626 [(set (match_operand:HI 0 "register_operand")
3627 (mem:HI (plus:SI (match_dup 0)
3628 (match_operand:SI 1 "const_int_operand"))))]
3629 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3630 && REG_P (operands[0])
3631 && M16_REG_P (REGNO (operands[0]))
3632 && GET_CODE (operands[1]) == CONST_INT
3633 && ((INTVAL (operands[1]) < 0
3634 && INTVAL (operands[1]) >= -0x80)
3635 || (INTVAL (operands[1]) >= 32 * 2
3636 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3637 || (INTVAL (operands[1]) >= 0
3638 && INTVAL (operands[1]) < 32 * 2
3639 && (INTVAL (operands[1]) & 1) != 0))"
3640 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3641 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3642{
3643 HOST_WIDE_INT val = INTVAL (operands[1]);
3644
3645 if (val < 0)
3646 operands[2] = const0_rtx;
3647 else if (val >= 32 * 2)
3648 {
3649 int off = val & 1;
3650
3651 operands[1] = GEN_INT (0x7e + off);
3652 operands[2] = GEN_INT (val - off - 0x7e);
3653 }
3654 else
3655 {
3656 int off = val & 1;
3657
3658 operands[1] = GEN_INT (off);
3659 operands[2] = GEN_INT (val - off);
3660 }
3661})
3662
3663;; 8-bit Integer moves
3664
3665;; Unlike most other insns, the move insns can't be split with
3666;; different predicates, because register spilling and other parts of
3667;; the compiler, have memoized the insn number already.
3668;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3669
3670(define_expand "movqi"
3671 [(set (match_operand:QI 0 "")
3672 (match_operand:QI 1 ""))]
3673 ""
3674{
3675 if (mips_legitimize_move (QImode, operands[0], operands[1]))
3676 DONE;
3677})
3678
3679(define_insn "*movqi_internal"
3680 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3681 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3682 "!TARGET_MIPS16
3683 && (register_operand (operands[0], QImode)
3684 || reg_or_0_operand (operands[1], QImode))"
3685 "@
3686 move\t%0,%1
3687 li\t%0,%1
3688 lbu\t%0,%1
3689 sb\t%z1,%0
3690 mfc1\t%0,%1
3691 mtc1\t%1,%0
3692 mov.s\t%0,%1
3693 mt%0\t%1"
3694 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3695 (set_attr "mode" "QI")
3696 (set_attr "length" "4,4,*,*,4,4,4,4")])
3697
3698(define_insn "*movqi_mips16"
3699 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3700 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
3701 "TARGET_MIPS16
3702 && (register_operand (operands[0], QImode)
3703 || register_operand (operands[1], QImode))"
3704 "@
3705 move\t%0,%1
3706 move\t%0,%1
3707 move\t%0,%1
3708 li\t%0,%1
3709 #
3710 lbu\t%0,%1
3711 sb\t%1,%0"
3712 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3713 (set_attr "mode" "QI")
3714 (set_attr "length" "4,4,4,4,8,*,*")])
3715
3716;; On the mips16, we can split lb $r,N($r) into an add and a load,
3717;; when the original load is a 4 byte instruction but the add and the
3718;; load are 2 2 byte instructions.
3719
3720(define_split
3721 [(set (match_operand:QI 0 "register_operand")
3722 (mem:QI (plus:SI (match_dup 0)
3723 (match_operand:SI 1 "const_int_operand"))))]
3724 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3725 && REG_P (operands[0])
3726 && M16_REG_P (REGNO (operands[0]))
3727 && GET_CODE (operands[1]) == CONST_INT
3728 && ((INTVAL (operands[1]) < 0
3729 && INTVAL (operands[1]) >= -0x80)
3730 || (INTVAL (operands[1]) >= 32
3731 && INTVAL (operands[1]) <= 31 + 0x7f))"
3732 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3733 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3734{
3735 HOST_WIDE_INT val = INTVAL (operands[1]);
3736
3737 if (val < 0)
3738 operands[2] = const0_rtx;
3739 else
3740 {
3741 operands[1] = GEN_INT (0x7f);
3742 operands[2] = GEN_INT (val - 0x7f);
3743 }
3744})
3745
3746;; 32-bit floating point moves
3747
3748(define_expand "movsf"
3749 [(set (match_operand:SF 0 "")
3750 (match_operand:SF 1 ""))]
3751 ""
3752{
3753 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3754 DONE;
3755})
3756
3757(define_insn "*movsf_hardfloat"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3759 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3760 "TARGET_HARD_FLOAT
3761 && (register_operand (operands[0], SFmode)
3762 || reg_or_0_operand (operands[1], SFmode))"
3763 { return mips_output_move (operands[0], operands[1]); }
3764 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3765 (set_attr "mode" "SF")
3766 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3767
3768(define_insn "*movsf_softfloat"
3769 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3770 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3771 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3772 && (register_operand (operands[0], SFmode)
3773 || reg_or_0_operand (operands[1], SFmode))"
3774 { return mips_output_move (operands[0], operands[1]); }
3775 [(set_attr "type" "arith,load,store")
3776 (set_attr "mode" "SF")
3777 (set_attr "length" "4,*,*")])
3778
3779(define_insn "*movsf_mips16"
3780 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3781 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3782 "TARGET_MIPS16
3783 && (register_operand (operands[0], SFmode)
3784 || register_operand (operands[1], SFmode))"
3785 { return mips_output_move (operands[0], operands[1]); }
3786 [(set_attr "type" "arith,arith,arith,load,store")
3787 (set_attr "mode" "SF")
3788 (set_attr "length" "4,4,4,*,*")])
3789
3790
3791;; 64-bit floating point moves
3792
3793(define_expand "movdf"
3794 [(set (match_operand:DF 0 "")
3795 (match_operand:DF 1 ""))]
3796 ""
3797{
3798 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3799 DONE;
3800})
3801
3802(define_insn "*movdf_hardfloat_64bit"
3803 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3804 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3805 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3806 && (register_operand (operands[0], DFmode)
3807 || reg_or_0_operand (operands[1], DFmode))"
3808 { return mips_output_move (operands[0], operands[1]); }
3809 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3810 (set_attr "mode" "DF")
3811 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3812
3813(define_insn "*movdf_hardfloat_32bit"
3814 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3815 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3816 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3817 && (register_operand (operands[0], DFmode)
3818 || reg_or_0_operand (operands[1], DFmode))"
3819 { return mips_output_move (operands[0], operands[1]); }
3820 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3821 (set_attr "mode" "DF")
3822 (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
3823
3824(define_insn "*movdf_softfloat"
3825 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3826 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3827 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3828 && (register_operand (operands[0], DFmode)
3829 || reg_or_0_operand (operands[1], DFmode))"
3830 { return mips_output_move (operands[0], operands[1]); }
3831 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
3832 (set_attr "mode" "DF")
3833 (set_attr "length" "8,*,*,4,4,4")])
3834
3835(define_insn "*movdf_mips16"
3836 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3837 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3838 "TARGET_MIPS16
3839 && (register_operand (operands[0], DFmode)
3840 || register_operand (operands[1], DFmode))"
3841 { return mips_output_move (operands[0], operands[1]); }
3842 [(set_attr "type" "arith,arith,arith,load,store")
3843 (set_attr "mode" "DF")
3844 (set_attr "length" "8,8,8,*,*")])
3845
3846(define_split
3847 [(set (match_operand:DI 0 "nonimmediate_operand")
3848 (match_operand:DI 1 "move_operand"))]
3849 "reload_completed && !TARGET_64BIT
3850 && mips_split_64bit_move_p (operands[0], operands[1])"
3851 [(const_int 0)]
3852{
3853 mips_split_64bit_move (operands[0], operands[1]);
3854 DONE;
3855})
3856
3857(define_split
3858 [(set (match_operand:DF 0 "nonimmediate_operand")
3859 (match_operand:DF 1 "move_operand"))]
3860 "reload_completed && !TARGET_64BIT
3861 && mips_split_64bit_move_p (operands[0], operands[1])"
3862 [(const_int 0)]
3863{
3864 mips_split_64bit_move (operands[0], operands[1]);
3865 DONE;
3866})
3867
3868;; When generating mips16 code, split moves of negative constants into
3869;; a positive "li" followed by a negation.
3870(define_split
3871 [(set (match_operand 0 "register_operand")
3872 (match_operand 1 "const_int_operand"))]
3873 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3874 [(set (match_dup 2)
3875 (match_dup 3))
3876 (set (match_dup 2)
3877 (neg:SI (match_dup 2)))]
3878{
3879 operands[2] = gen_lowpart (SImode, operands[0]);
3880 operands[3] = GEN_INT (-INTVAL (operands[1]));
3881})
3882
3883;; 64-bit paired-single floating point moves
3884
3885(define_expand "movv2sf"
3886 [(set (match_operand:V2SF 0)
3887 (match_operand:V2SF 1))]
3888 "TARGET_PAIRED_SINGLE_FLOAT"
3889{
3890 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3891 DONE;
3892})
3893
3894(define_insn "movv2sf_hardfloat_64bit"
3895 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3896 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
3897 "TARGET_PAIRED_SINGLE_FLOAT
3898 && TARGET_64BIT
3899 && (register_operand (operands[0], V2SFmode)
3900 || reg_or_0_operand (operands[1], V2SFmode))"
3901 { return mips_output_move (operands[0], operands[1]); }
3902 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3903 (set_attr "mode" "SF")
3904 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3905
3906;; The HI and LO registers are not truly independent. If we move an mthi
3907;; instruction before an mflo instruction, it will make the result of the
3908;; mflo unpredictable. The same goes for mtlo and mfhi.
3909;;
3910;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3911;; Operand 1 is the register we want, operand 2 is the other one.
3912;;
3913;; When generating VR4120 or VR4130 code, we use macc{,hi} and
3914;; dmacc{,hi} instead of mfhi and mflo. This avoids both the normal
3915;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
3916
3917(define_expand "mfhilo_<mode>"
3918 [(set (match_operand:GPR 0 "register_operand")
3919 (unspec:GPR [(match_operand:GPR 1 "register_operand")
3920 (match_operand:GPR 2 "register_operand")]
3921 UNSPEC_MFHILO))])
3922
3923(define_insn "*mfhilo_<mode>"
3924 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3925 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3926 (match_operand:GPR 2 "register_operand" "l,h")]
3927 UNSPEC_MFHILO))]
3928 "!ISA_HAS_MACCHI"
3929 "mf%1\t%0"
3930 [(set_attr "type" "mfhilo")
3931 (set_attr "mode" "<MODE>")])
3932
3933(define_insn "*mfhilo_<mode>_macc"
3934 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3935 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3936 (match_operand:GPR 2 "register_operand" "l,h")]
3937 UNSPEC_MFHILO))]
3938 "ISA_HAS_MACCHI"
3939{
3940 if (REGNO (operands[1]) == HI_REGNUM)
3941 return "<d>macchi\t%0,%.,%.";
3942 else
3943 return "<d>macc\t%0,%.,%.";
3944}
3945 [(set_attr "type" "mfhilo")
3946 (set_attr "mode" "<MODE>")])
3947
3948;; Patterns for loading or storing part of a paired floating point
3949;; register. We need them because odd-numbered floating-point registers
3950;; are not fully independent: see mips_split_64bit_move.
3951
3952;; Load the low word of operand 0 with operand 1.
3953(define_insn "load_df_low"
3954 [(set (match_operand:DF 0 "register_operand" "=f,f")
3955 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3956 UNSPEC_LOAD_DF_LOW))]
3957 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3958{
3959 operands[0] = mips_subword (operands[0], 0);
3960 return mips_output_move (operands[0], operands[1]);
3961}
3962 [(set_attr "type" "xfer,fpload")
3963 (set_attr "mode" "SF")])
3964
3965;; Load the high word of operand 0 from operand 1, preserving the value
3966;; in the low word.
3967(define_insn "load_df_high"
3968 [(set (match_operand:DF 0 "register_operand" "=f,f")
3969 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3970 (match_operand:DF 2 "register_operand" "0,0")]
3971 UNSPEC_LOAD_DF_HIGH))]
3972 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3973{
3974 operands[0] = mips_subword (operands[0], 1);
3975 return mips_output_move (operands[0], operands[1]);
3976}
3977 [(set_attr "type" "xfer,fpload")
3978 (set_attr "mode" "SF")])
3979
3980;; Store the high word of operand 1 in operand 0. The corresponding
3981;; low-word move is done in the normal way.
3982(define_insn "store_df_high"
3983 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3984 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
3985 UNSPEC_STORE_DF_HIGH))]
3986 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3987{
3988 operands[1] = mips_subword (operands[1], 1);
3989 return mips_output_move (operands[0], operands[1]);
3990}
3991 [(set_attr "type" "xfer,fpstore")
3992 (set_attr "mode" "SF")])
3993
3994;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
3995;; of _gp from the start of this function. Operand 1 is the incoming
3996;; function address.
3997(define_insn_and_split "loadgp"
3998 [(unspec_volatile [(match_operand 0 "" "")
3999 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4000 "mips_current_loadgp_style () == LOADGP_NEWABI"
4001 "#"
4002 ""
4003 [(set (match_dup 2) (match_dup 3))
4004 (set (match_dup 2) (match_dup 4))
4005 (set (match_dup 2) (match_dup 5))]
4006{
4007 operands[2] = pic_offset_table_rtx;
4008 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4009 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4010 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4011}
4012 [(set_attr "length" "12")])
4013
4014;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
4015(define_insn_and_split "loadgp_noshared"
4016 [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4017 "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4018 "#"
4019 ""
4020 [(const_int 0)]
4021{
4022 emit_move_insn (pic_offset_table_rtx, operands[0]);
4023 DONE;
4024}
4025 [(set_attr "length" "8")])
4026
4027;; The use of gp is hidden when not using explicit relocations.
4028;; This blockage instruction prevents the gp load from being
4029;; scheduled after an implicit use of gp. It also prevents
4030;; the load from being deleted as dead.
4031(define_insn "loadgp_blockage"
4032 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4033 ""
4034 ""
4035 [(set_attr "type" "unknown")
4036 (set_attr "mode" "none")
4037 (set_attr "length" "0")])
4038
4039;; Emit a .cprestore directive, which normally expands to a single store
4040;; instruction. Note that we continue to use .cprestore for explicit reloc
4041;; code so that jals inside inline asms will work correctly.
4042(define_insn "cprestore"
4043 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4044 UNSPEC_CPRESTORE)]
4045 ""
4046{
4047 if (set_nomacro && which_alternative == 1)
4048 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4049 else
4050 return ".cprestore\t%0";
4051}
4052 [(set_attr "type" "store")
4053 (set_attr "length" "4,12")])
4054
4055;; Block moves, see mips.c for more details.
4056;; Argument 0 is the destination
4057;; Argument 1 is the source
4058;; Argument 2 is the length
4059;; Argument 3 is the alignment
4060
4061(define_expand "movmemsi"
4062 [(parallel [(set (match_operand:BLK 0 "general_operand")
4063 (match_operand:BLK 1 "general_operand"))
4064 (use (match_operand:SI 2 ""))
4065 (use (match_operand:SI 3 "const_int_operand"))])]
4066 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4067{
4068 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4069 DONE;
4070 else
4071 FAIL;
4072})
4073
4074;;
4075;; ....................
4076;;
4077;; SHIFTS
4078;;
4079;; ....................
4080
4081(define_expand "<optab><mode>3"
4082 [(set (match_operand:GPR 0 "register_operand")
4083 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4084 (match_operand:SI 2 "arith_operand")))]
4085 ""
4086{
4087 /* On the mips16, a shift of more than 8 is a four byte instruction,
4088 so, for a shift between 8 and 16, it is just as fast to do two
4089 shifts of 8 or less. If there is a lot of shifting going on, we
4090 may win in CSE. Otherwise combine will put the shifts back
4091 together again. This can be called by function_arg, so we must
4092 be careful not to allocate a new register if we've reached the
4093 reload pass. */
4094 if (TARGET_MIPS16
4095 && optimize
4096 && GET_CODE (operands[2]) == CONST_INT
4097 && INTVAL (operands[2]) > 8
4098 && INTVAL (operands[2]) <= 16
4099 && !reload_in_progress
4100 && !reload_completed)
4101 {
4102 rtx temp = gen_reg_rtx (<MODE>mode);
4103
4104 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4105 emit_insn (gen_<optab><mode>3 (operands[0], temp,
4106 GEN_INT (INTVAL (operands[2]) - 8)));
4107 DONE;
4108 }
4109})
4110
4111(define_insn "*<optab><mode>3"
4112 [(set (match_operand:GPR 0 "register_operand" "=d")
4113 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4114 (match_operand:SI 2 "arith_operand" "dI")))]
4115 "!TARGET_MIPS16"
4116{
4117 if (GET_CODE (operands[2]) == CONST_INT)
4118 operands[2] = GEN_INT (INTVAL (operands[2])
4119 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4120
4121 return "<d><insn>\t%0,%1,%2";
4122}
4123 [(set_attr "type" "shift")
4124 (set_attr "mode" "<MODE>")])
4125
4126(define_insn "*<optab>si3_extend"
4127 [(set (match_operand:DI 0 "register_operand" "=d")
4128 (sign_extend:DI
4129 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4130 (match_operand:SI 2 "arith_operand" "dI"))))]
4131 "TARGET_64BIT && !TARGET_MIPS16"
4132{
4133 if (GET_CODE (operands[2]) == CONST_INT)
4134 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4135
4136 return "<insn>\t%0,%1,%2";
4137}
4138 [(set_attr "type" "shift")
4139 (set_attr "mode" "SI")])
4140
4141(define_insn "*<optab>si3_mips16"
4142 [(set (match_operand:SI 0 "register_operand" "=d,d")
4143 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4144 (match_operand:SI 2 "arith_operand" "d,I")))]
4145 "TARGET_MIPS16"
4146{
4147 if (which_alternative == 0)
4148 return "<insn>\t%0,%2";
4149
4150 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4151 return "<insn>\t%0,%1,%2";
4152}
4153 [(set_attr "type" "shift")
4154 (set_attr "mode" "SI")
4155 (set_attr_alternative "length"
4156 [(const_int 4)
4157 (if_then_else (match_operand 2 "m16_uimm3_b")
4158 (const_int 4)
4159 (const_int 8))])])
4160
4161;; We need separate DImode MIPS16 patterns because of the irregularity
4162;; of right shifts.
4163(define_insn "*ashldi3_mips16"
4164 [(set (match_operand:DI 0 "register_operand" "=d,d")
4165 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4166 (match_operand:SI 2 "arith_operand" "d,I")))]
4167 "TARGET_64BIT && TARGET_MIPS16"
4168{
4169 if (which_alternative == 0)
4170 return "dsll\t%0,%2";
4171
4172 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4173 return "dsll\t%0,%1,%2";
4174}
4175 [(set_attr "type" "shift")
4176 (set_attr "mode" "DI")
4177 (set_attr_alternative "length"
4178 [(const_int 4)
4179 (if_then_else (match_operand 2 "m16_uimm3_b")
4180 (const_int 4)
4181 (const_int 8))])])
4182
4183(define_insn "*ashrdi3_mips16"
4184 [(set (match_operand:DI 0 "register_operand" "=d,d")
4185 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4186 (match_operand:SI 2 "arith_operand" "d,I")))]
4187 "TARGET_64BIT && TARGET_MIPS16"
4188{
4189 if (GET_CODE (operands[2]) == CONST_INT)
4190 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4191
4192 return "dsra\t%0,%2";
4193}
4194 [(set_attr "type" "shift")
4195 (set_attr "mode" "DI")
4196 (set_attr_alternative "length"
4197 [(const_int 4)
4198 (if_then_else (match_operand 2 "m16_uimm3_b")
4199 (const_int 4)
4200 (const_int 8))])])
4201
4202(define_insn "*lshrdi3_mips16"
4203 [(set (match_operand:DI 0 "register_operand" "=d,d")
4204 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4205 (match_operand:SI 2 "arith_operand" "d,I")))]
4206 "TARGET_64BIT && TARGET_MIPS16"
4207{
4208 if (GET_CODE (operands[2]) == CONST_INT)
4209 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4210
4211 return "dsrl\t%0,%2";
4212}
4213 [(set_attr "type" "shift")
4214 (set_attr "mode" "DI")
4215 (set_attr_alternative "length"
4216 [(const_int 4)
4217 (if_then_else (match_operand 2 "m16_uimm3_b")
4218 (const_int 4)
4219 (const_int 8))])])
4220
4221;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4222
4223(define_split
4224 [(set (match_operand:GPR 0 "register_operand")
4225 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4226 (match_operand:GPR 2 "const_int_operand")))]
4227 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4228 && GET_CODE (operands[2]) == CONST_INT
4229 && INTVAL (operands[2]) > 8
4230 && INTVAL (operands[2]) <= 16"
4231 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4232 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4233 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4234
4235;; If we load a byte on the mips16 as a bitfield, the resulting
4236;; sequence of instructions is too complicated for combine, because it
4237;; involves four instructions: a load, a shift, a constant load into a
4238;; register, and an and (the key problem here is that the mips16 does
4239;; not have and immediate). We recognize a shift of a load in order
4240;; to make it simple enough for combine to understand.
4241;;
4242;; The length here is the worst case: the length of the split version
4243;; will be more accurate.
4244(define_insn_and_split ""
4245 [(set (match_operand:SI 0 "register_operand" "=d")
4246 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4247 (match_operand:SI 2 "immediate_operand" "I")))]
4248 "TARGET_MIPS16"
4249 "#"
4250 ""
4251 [(set (match_dup 0) (match_dup 1))
4252 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4253 ""
4254 [(set_attr "type" "load")
4255 (set_attr "mode" "SI")
4256 (set_attr "length" "16")])
4257
4258(define_insn "rotr<mode>3"
4259 [(set (match_operand:GPR 0 "register_operand" "=d")
4260 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4261 (match_operand:SI 2 "arith_operand" "dI")))]
4262 "ISA_HAS_ROTR_<MODE>"
4263{
4264 if (GET_CODE (operands[2]) == CONST_INT)
4265 gcc_assert (INTVAL (operands[2]) >= 0
4266 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4267
4268 return "<d>ror\t%0,%1,%2";
4269}
4270 [(set_attr "type" "shift")
4271 (set_attr "mode" "<MODE>")])
4272
4273;;
4274;; ....................
4275;;
4276;; COMPARISONS
4277;;
4278;; ....................
4279
4280;; Flow here is rather complex:
4281;;
4282;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
4283;; into cmp_operands[] but generates no RTL.
4284;;
4285;; 2) The appropriate branch define_expand is called, which then
4286;; creates the appropriate RTL for the comparison and branch.
4287;; Different CC modes are used, based on what type of branch is
4288;; done, so that we can constrain things appropriately. There
4289;; are assumptions in the rest of GCC that break if we fold the
4290;; operands into the branches for integer operations, and use cc0
4291;; for floating point, so we use the fp status register instead.
4292;; If needed, an appropriate temporary is created to hold the
4293;; of the integer compare.
4294
4295(define_expand "cmp<mode>"
4296 [(set (cc0)
4297 (compare:CC (match_operand:GPR 0 "register_operand")
4298 (match_operand:GPR 1 "nonmemory_operand")))]
4299 ""
4300{
4301 cmp_operands[0] = operands[0];
4302 cmp_operands[1] = operands[1];
4303 DONE;
4304})
4305
4306(define_expand "cmp<mode>"
4307 [(set (cc0)
4308 (compare:CC (match_operand:SCALARF 0 "register_operand")
4309 (match_operand:SCALARF 1 "register_operand")))]
4310 ""
4311{
4312 cmp_operands[0] = operands[0];
4313 cmp_operands[1] = operands[1];
4314 DONE;
4315})
4316
4317;;
4318;; ....................
4319;;
4320;; CONDITIONAL BRANCHES
4321;;
4322;; ....................
4323
4324;; Conditional branches on floating-point equality tests.
4325
4326(define_insn "*branch_fp"
4327 [(set (pc)
4328 (if_then_else
4329 (match_operator 0 "equality_operator"
4330 [(match_operand:CC 2 "register_operand" "z")
4331 (const_int 0)])
4332 (label_ref (match_operand 1 "" ""))
4333 (pc)))]
4334 "TARGET_HARD_FLOAT"
4335{
4336 return mips_output_conditional_branch (insn, operands,
4337 MIPS_BRANCH ("b%F0", "%Z2%1"),
4338 MIPS_BRANCH ("b%W0", "%Z2%1"));
4339}
4340 [(set_attr "type" "branch")
4341 (set_attr "mode" "none")])
4342
4343(define_insn "*branch_fp_inverted"
4344 [(set (pc)
4345 (if_then_else
4346 (match_operator 0 "equality_operator"
4347 [(match_operand:CC 2 "register_operand" "z")
4348 (const_int 0)])
4349 (pc)
4350 (label_ref (match_operand 1 "" ""))))]
4351 "TARGET_HARD_FLOAT"
4352{
4353 return mips_output_conditional_branch (insn, operands,
4354 MIPS_BRANCH ("b%W0", "%Z2%1"),
4355 MIPS_BRANCH ("b%F0", "%Z2%1"));
4356}
4357 [(set_attr "type" "branch")
4358 (set_attr "mode" "none")])
4359
4360;; Conditional branches on ordered comparisons with zero.
4361
4362(define_insn "*branch_order<mode>"
4363 [(set (pc)
4364 (if_then_else
4365 (match_operator 0 "order_operator"
4366 [(match_operand:GPR 2 "register_operand" "d")
4367 (const_int 0)])
4368 (label_ref (match_operand 1 "" ""))
4369 (pc)))]
4370 "!TARGET_MIPS16"
4371 { return mips_output_order_conditional_branch (insn, operands, false); }
4372 [(set_attr "type" "branch")
4373 (set_attr "mode" "none")])
4374
4375(define_insn "*branch_order<mode>_inverted"
4376 [(set (pc)
4377 (if_then_else
4378 (match_operator 0 "order_operator"
4379 [(match_operand:GPR 2 "register_operand" "d")
4380 (const_int 0)])
4381 (pc)
4382 (label_ref (match_operand 1 "" ""))))]
4383 "!TARGET_MIPS16"
4384 { return mips_output_order_conditional_branch (insn, operands, true); }
4385 [(set_attr "type" "branch")
4386 (set_attr "mode" "none")])
4387
4388;; Conditional branch on equality comparison.
4389
4390(define_insn "*branch_equality<mode>"
4391 [(set (pc)
4392 (if_then_else
4393 (match_operator 0 "equality_operator"
4394 [(match_operand:GPR 2 "register_operand" "d")
4395 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4396 (label_ref (match_operand 1 "" ""))
4397 (pc)))]
4398 "!TARGET_MIPS16"
4399{
4400 return mips_output_conditional_branch (insn, operands,
4401 MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4402 MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4403}
4404 [(set_attr "type" "branch")
4405 (set_attr "mode" "none")])
4406
4407(define_insn "*branch_equality<mode>_inverted"
4408 [(set (pc)
4409 (if_then_else
4410 (match_operator 0 "equality_operator"
4411 [(match_operand:GPR 2 "register_operand" "d")
4412 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4413 (pc)
4414 (label_ref (match_operand 1 "" ""))))]
4415 "!TARGET_MIPS16"
4416{
4417 return mips_output_conditional_branch (insn, operands,
4418 MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4419 MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4420}
4421 [(set_attr "type" "branch")
4422 (set_attr "mode" "none")])
4423
4424;; MIPS16 branches
4425
4426(define_insn "*branch_equality<mode>_mips16"
4427 [(set (pc)
4428 (if_then_else
4429 (match_operator 0 "equality_operator"
4430 [(match_operand:GPR 1 "register_operand" "d,t")
4431 (const_int 0)])
4432 (match_operand 2 "pc_or_label_operand" "")
4433 (match_operand 3 "pc_or_label_operand" "")))]
4434 "TARGET_MIPS16"
4435{
4436 if (operands[2] != pc_rtx)
4437 {
4438 if (which_alternative == 0)
4439 return "b%C0z\t%1,%2";
4440 else
4441 return "bt%C0z\t%2";
4442 }
4443 else
4444 {
4445 if (which_alternative == 0)
4446 return "b%N0z\t%1,%3";
4447 else
4448 return "bt%N0z\t%3";
4449 }
4450}
4451 [(set_attr "type" "branch")
4452 (set_attr "mode" "none")
4453 (set_attr "length" "8")])
4454
4455(define_expand "b<code>"
4456 [(set (pc)
4457 (if_then_else (any_cond:CC (cc0)
4458 (const_int 0))
4459 (label_ref (match_operand 0 ""))
4460 (pc)))]
4461 ""
4462{
4463 gen_conditional_branch (operands, <CODE>);
4464 DONE;
4465})
4466
4467;; Used to implement built-in functions.
4468(define_expand "condjump"
4469 [(set (pc)
4470 (if_then_else (match_operand 0)
4471 (label_ref (match_operand 1))
4472 (pc)))])
4473
4474;;
4475;; ....................
4476;;
4477;; SETTING A REGISTER FROM A COMPARISON
4478;;
4479;; ....................
4480
4481(define_expand "seq"
4482 [(set (match_operand:SI 0 "register_operand")
4483 (eq:SI (match_dup 1)
4484 (match_dup 2)))]
4485 ""
4486 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4487
4488(define_insn "*seq_<mode>"
4489 [(set (match_operand:GPR 0 "register_operand" "=d")
4490 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4491 (const_int 0)))]
4492 "!TARGET_MIPS16"
4493 "sltu\t%0,%1,1"
4494 [(set_attr "type" "slt")
4495 (set_attr "mode" "<MODE>")])
4496
4497(define_insn "*seq_<mode>_mips16"
4498 [(set (match_operand:GPR 0 "register_operand" "=t")
4499 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4500 (const_int 0)))]
4501 "TARGET_MIPS16"
4502 "sltu\t%1,1"
4503 [(set_attr "type" "slt")
4504 (set_attr "mode" "<MODE>")])
4505
4506;; "sne" uses sltu instructions in which the first operand is $0.
4507;; This isn't possible in mips16 code.
4508
4509(define_expand "sne"
4510 [(set (match_operand:SI 0 "register_operand")
4511 (ne:SI (match_dup 1)
4512 (match_dup 2)))]
4513 "!TARGET_MIPS16"
4514 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4515
4516(define_insn "*sne_<mode>"
4517 [(set (match_operand:GPR 0 "register_operand" "=d")
4518 (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4519 (const_int 0)))]
4520 "!TARGET_MIPS16"
4521 "sltu\t%0,%.,%1"
4522 [(set_attr "type" "slt")
4523 (set_attr "mode" "<MODE>")])
4524
4525(define_expand "sgt"
4526 [(set (match_operand:SI 0 "register_operand")
4527 (gt:SI (match_dup 1)
4528 (match_dup 2)))]
4529 ""
4530 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4531
4532(define_insn "*sgt_<mode>"
4533 [(set (match_operand:GPR 0 "register_operand" "=d")
4534 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4535 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4536 "!TARGET_MIPS16"
4537 "slt\t%0,%z2,%1"
4538 [(set_attr "type" "slt")
4539 (set_attr "mode" "<MODE>")])
4540
4541(define_insn "*sgt_<mode>_mips16"
4542 [(set (match_operand:GPR 0 "register_operand" "=t")
4543 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4544 (match_operand:GPR 2 "register_operand" "d")))]
4545 "TARGET_MIPS16"
4546 "slt\t%2,%1"
4547 [(set_attr "type" "slt")
4548 (set_attr "mode" "<MODE>")])
4549
4550(define_expand "sge"
4551 [(set (match_operand:SI 0 "register_operand")
4552 (ge:SI (match_dup 1)
4553 (match_dup 2)))]
4554 ""
4555 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4556
4557(define_insn "*sge_<mode>"
4558 [(set (match_operand:GPR 0 "register_operand" "=d")
4559 (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4560 (const_int 1)))]
4561 "!TARGET_MIPS16"
4562 "slt\t%0,%.,%1"
4563 [(set_attr "type" "slt")
4564 (set_attr "mode" "<MODE>")])
4565
4566(define_expand "slt"
4567 [(set (match_operand:SI 0 "register_operand")
4568 (lt:SI (match_dup 1)
4569 (match_dup 2)))]
4570 ""
4571 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4572
4573(define_insn "*slt_<mode>"
4574 [(set (match_operand:GPR 0 "register_operand" "=d")
4575 (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4576 (match_operand:GPR 2 "arith_operand" "dI")))]
4577 "!TARGET_MIPS16"
4578 "slt\t%0,%1,%2"
4579 [(set_attr "type" "slt")
4580 (set_attr "mode" "<MODE>")])
4581
4582(define_insn "*slt_<mode>_mips16"
4583 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4584 (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4585 (match_operand:GPR 2 "arith_operand" "d,I")))]
4586 "TARGET_MIPS16"
4587 "slt\t%1,%2"
4588 [(set_attr "type" "slt")
4589 (set_attr "mode" "<MODE>")
4590 (set_attr_alternative "length"
4591 [(const_int 4)
4592 (if_then_else (match_operand 2 "m16_uimm8_1")
4593 (const_int 4)
4594 (const_int 8))])])
4595
4596(define_expand "sle"
4597 [(set (match_operand:SI 0 "register_operand")
4598 (le:SI (match_dup 1)
4599 (match_dup 2)))]
4600 ""
4601 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4602
4603(define_insn "*sle_<mode>"
4604 [(set (match_operand:GPR 0 "register_operand" "=d")
4605 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4606 (match_operand:GPR 2 "sle_operand" "")))]
4607 "!TARGET_MIPS16"
4608{
4609 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4610 return "slt\t%0,%1,%2";
4611}
4612 [(set_attr "type" "slt")
4613 (set_attr "mode" "<MODE>")])
4614
4615(define_insn "*sle_<mode>_mips16"
4616 [(set (match_operand:GPR 0 "register_operand" "=t")
4617 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4618 (match_operand:GPR 2 "sle_operand" "")))]
4619 "TARGET_MIPS16"
4620{
4621 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4622 return "slt\t%1,%2";
4623}
4624 [(set_attr "type" "slt")
4625 (set_attr "mode" "<MODE>")
4626 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4627 (const_int 4)
4628 (const_int 8)))])
4629
4630(define_expand "sgtu"
4631 [(set (match_operand:SI 0 "register_operand")
4632 (gtu:SI (match_dup 1)
4633 (match_dup 2)))]
4634 ""
4635 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4636
4637(define_insn "*sgtu_<mode>"
4638 [(set (match_operand:GPR 0 "register_operand" "=d")
4639 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4640 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4641 "!TARGET_MIPS16"
4642 "sltu\t%0,%z2,%1"
4643 [(set_attr "type" "slt")
4644 (set_attr "mode" "<MODE>")])
4645
4646(define_insn "*sgtu_<mode>_mips16"
4647 [(set (match_operand:GPR 0 "register_operand" "=t")
4648 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4649 (match_operand:GPR 2 "register_operand" "d")))]
4650 "TARGET_MIPS16"
4651 "sltu\t%2,%1"
4652 [(set_attr "type" "slt")
4653 (set_attr "mode" "<MODE>")])
4654
4655(define_expand "sgeu"
4656 [(set (match_operand:SI 0 "register_operand")
4657 (geu:SI (match_dup 1)
4658 (match_dup 2)))]
4659 ""
4660 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4661
4662(define_insn "*sge_<mode>"
4663 [(set (match_operand:GPR 0 "register_operand" "=d")
4664 (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4665 (const_int 1)))]
4666 "!TARGET_MIPS16"
4667 "sltu\t%0,%.,%1"
4668 [(set_attr "type" "slt")
4669 (set_attr "mode" "<MODE>")])
4670
4671(define_expand "sltu"
4672 [(set (match_operand:SI 0 "register_operand")
4673 (ltu:SI (match_dup 1)
4674 (match_dup 2)))]
4675 ""
4676 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4677
4678(define_insn "*sltu_<mode>"
4679 [(set (match_operand:GPR 0 "register_operand" "=d")
4680 (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4681 (match_operand:GPR 2 "arith_operand" "dI")))]
4682 "!TARGET_MIPS16"
4683 "sltu\t%0,%1,%2"
4684 [(set_attr "type" "slt")
4685 (set_attr "mode" "<MODE>")])
4686
4687(define_insn "*sltu_<mode>_mips16"
4688 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4689 (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4690 (match_operand:GPR 2 "arith_operand" "d,I")))]
4691 "TARGET_MIPS16"
4692 "sltu\t%1,%2"
4693 [(set_attr "type" "slt")
4694 (set_attr "mode" "<MODE>")
4695 (set_attr_alternative "length"
4696 [(const_int 4)
4697 (if_then_else (match_operand 2 "m16_uimm8_1")
4698 (const_int 4)
4699 (const_int 8))])])
4700
4701(define_expand "sleu"
4702 [(set (match_operand:SI 0 "register_operand")
4703 (leu:SI (match_dup 1)
4704 (match_dup 2)))]
4705 ""
4706 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4707
4708(define_insn "*sleu_<mode>"
4709 [(set (match_operand:GPR 0 "register_operand" "=d")
4710 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4711 (match_operand:GPR 2 "sleu_operand" "")))]
4712 "!TARGET_MIPS16"
4713{
4714 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4715 return "sltu\t%0,%1,%2";
4716}
4717 [(set_attr "type" "slt")
4718 (set_attr "mode" "<MODE>")])
4719
4720(define_insn "*sleu_<mode>_mips16"
4721 [(set (match_operand:GPR 0 "register_operand" "=t")
4722 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4723 (match_operand:GPR 2 "sleu_operand" "")))]
4724 "TARGET_MIPS16"
4725{
4726 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4727 return "sltu\t%1,%2";
4728}
4729 [(set_attr "type" "slt")
4730 (set_attr "mode" "<MODE>")
4731 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4732 (const_int 4)
4733 (const_int 8)))])
4734
4735;;
4736;; ....................
4737;;
4738;; FLOATING POINT COMPARISONS
4739;;
4740;; ....................
4741
4742(define_insn "s<code>_<mode>"
4743 [(set (match_operand:CC 0 "register_operand" "=z")
4744 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4745 (match_operand:SCALARF 2 "register_operand" "f")))]
4746 ""
4747 "c.<fcond>.<fmt>\t%Z0%1,%2"
4748 [(set_attr "type" "fcmp")
4749 (set_attr "mode" "FPSW")])
4750
4751(define_insn "s<code>_<mode>"
4752 [(set (match_operand:CC 0 "register_operand" "=z")
4753 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4754 (match_operand:SCALARF 2 "register_operand" "f")))]
4755 ""
4756 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
4757 [(set_attr "type" "fcmp")
4758 (set_attr "mode" "FPSW")])
4759
4760;;
4761;; ....................
4762;;
4763;; UNCONDITIONAL BRANCHES
4764;;
4765;; ....................
4766
4767;; Unconditional branches.
4768
4769(define_insn "jump"
4770 [(set (pc)
4771 (label_ref (match_operand 0 "" "")))]
4772 "!TARGET_MIPS16"
4773{
4774 if (flag_pic)
4775 {
4776 if (get_attr_length (insn) <= 8)
4777 return "%*b\t%l0%/";
4778 else
4779 {
4780 output_asm_insn (mips_output_load_label (), operands);
4781 return "%*jr\t%@%/%]";
4782 }
4783 }
4784 else
4785 return "%*j\t%l0%/";
4786}
4787 [(set_attr "type" "jump")
4788 (set_attr "mode" "none")
4789 (set (attr "length")
4790 ;; We can't use `j' when emitting PIC. Emit a branch if it's
4791 ;; in range, otherwise load the address of the branch target into
4792 ;; $at and then jump to it.
4793 (if_then_else
4794 (ior (eq (symbol_ref "flag_pic") (const_int 0))
4795 (lt (abs (minus (match_dup 0)
4796 (plus (pc) (const_int 4))))
4797 (const_int 131072)))
4798 (const_int 4) (const_int 16)))])
4799
4800;; We need a different insn for the mips16, because a mips16 branch
4801;; does not have a delay slot.
4802
4803(define_insn ""
4804 [(set (pc)
4805 (label_ref (match_operand 0 "" "")))]
4806 "TARGET_MIPS16"
4807 "b\t%l0"
4808 [(set_attr "type" "branch")
4809 (set_attr "mode" "none")
4810 (set_attr "length" "8")])
4811
4812(define_expand "indirect_jump"
4813 [(set (pc) (match_operand 0 "register_operand"))]
4814 ""
4815{
4816 operands[0] = force_reg (Pmode, operands[0]);
4817 if (Pmode == SImode)
4818 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
4819 else
4820 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
4821 DONE;
4822})
4823
4824(define_insn "indirect_jump<mode>"
4825 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
4826 ""
4827 "%*j\t%0%/"
4828 [(set_attr "type" "jump")
4829 (set_attr "mode" "none")])
4830
4831(define_expand "tablejump"
4832 [(set (pc)
4833 (match_operand 0 "register_operand"))
4834 (use (label_ref (match_operand 1 "")))]
4835 ""
4836{
4837 if (TARGET_MIPS16)
4838 operands[0] = expand_binop (Pmode, add_optab,
4839 convert_to_mode (Pmode, operands[0], false),
4840 gen_rtx_LABEL_REF (Pmode, operands[1]),
4841 0, 0, OPTAB_WIDEN);
4842 else if (TARGET_GPWORD)
4843 operands[0] = expand_binop (Pmode, add_optab, operands[0],
4844 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
4845
4846 if (Pmode == SImode)
4847 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
4848 else
4849 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
4850 DONE;
4851})
4852
4853(define_insn "tablejump<mode>"
4854 [(set (pc)
4855 (match_operand:P 0 "register_operand" "d"))
4856 (use (label_ref (match_operand 1 "" "")))]
4857 ""
4858 "%*j\t%0%/"
4859 [(set_attr "type" "jump")
4860 (set_attr "mode" "none")])
4861
4862;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
4863;; While it is possible to either pull it off the stack (in the
4864;; o32 case) or recalculate it given t9 and our target label,
4865;; it takes 3 or 4 insns to do so.
4866
4867(define_expand "builtin_setjmp_setup"
4868 [(use (match_operand 0 "register_operand"))]
4869 "TARGET_ABICALLS"
4870{
4871 rtx addr;
4872
4873 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
4874 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
4875 DONE;
4876})
4877
4878;; Restore the gp that we saved above. Despite the earlier comment, it seems
4879;; that older code did recalculate the gp from $25. Continue to jump through
4880;; $25 for compatibility (we lose nothing by doing so).
4881
4882(define_expand "builtin_longjmp"
4883 [(use (match_operand 0 "register_operand"))]
4884 "TARGET_ABICALLS"
4885{
4886 /* The elements of the buffer are, in order: */
4887 int W = GET_MODE_SIZE (Pmode);
4888 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
4889 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
4890 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
4891 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
4892 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
4893 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
4894 The target is bound to be using $28 as the global pointer
4895 but the current function might not be. */
4896 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
4897
4898 /* This bit is similar to expand_builtin_longjmp except that it
4899 restores $gp as well. */
4900 emit_move_insn (hard_frame_pointer_rtx, fp);
4901 emit_move_insn (pv, lab);
4902 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
4903 emit_move_insn (gp, gpv);
4904 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
4905 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4906 emit_insn (gen_rtx_USE (VOIDmode, gp));
4907 emit_indirect_jump (pv);
4908 DONE;
4909})
4910
4911;;
4912;; ....................
4913;;
4914;; Function prologue/epilogue
4915;;
4916;; ....................
4917;;
4918
4919(define_expand "prologue"
4920 [(const_int 1)]
4921 ""
4922{
4923 mips_expand_prologue ();
4924 DONE;
4925})
4926
4927;; Block any insns from being moved before this point, since the
4928;; profiling call to mcount can use various registers that aren't
4929;; saved or used to pass arguments.
4930
4931(define_insn "blockage"
4932 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4933 ""
4934 ""
4935 [(set_attr "type" "unknown")
4936 (set_attr "mode" "none")
4937 (set_attr "length" "0")])
4938
4939(define_expand "epilogue"
4940 [(const_int 2)]
4941 ""
4942{
4943 mips_expand_epilogue (false);
4944 DONE;
4945})
4946
4947(define_expand "sibcall_epilogue"
4948 [(const_int 2)]
4949 ""
4950{
4951 mips_expand_epilogue (true);
4952 DONE;
4953})
4954
4955;; Trivial return. Make it look like a normal return insn as that
4956;; allows jump optimizations to work better.
4957
4958(define_insn "return"
4959 [(return)]
4960 "mips_can_use_return_insn ()"
4961 "%*j\t$31%/"
4962 [(set_attr "type" "jump")
4963 (set_attr "mode" "none")])
4964
4965;; Normal return.
4966
4967(define_insn "return_internal"
4968 [(return)
4969 (use (match_operand 0 "pmode_register_operand" ""))]
4970 ""
4971 "%*j\t%0%/"
4972 [(set_attr "type" "jump")
4973 (set_attr "mode" "none")])
4974
4975;; This is used in compiling the unwind routines.
4976(define_expand "eh_return"
4977 [(use (match_operand 0 "general_operand"))]
4978 ""
4979{
4980 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
4981
4982 if (GET_MODE (operands[0]) != gpr_mode)
4983 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
4984 if (TARGET_64BIT)
4985 emit_insn (gen_eh_set_lr_di (operands[0]));
4986 else
4987 emit_insn (gen_eh_set_lr_si (operands[0]));
4988
4989 DONE;
4990})
4991
4992;; Clobber the return address on the stack. We can't expand this
4993;; until we know where it will be put in the stack frame.
4994
4995(define_insn "eh_set_lr_si"
4996 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
4997 (clobber (match_scratch:SI 1 "=&d"))]
4998 "! TARGET_64BIT"
4999 "#")
5000
5001(define_insn "eh_set_lr_di"
5002 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5003 (clobber (match_scratch:DI 1 "=&d"))]
5004 "TARGET_64BIT"
5005 "#")
5006
5007(define_split
5008 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5009 (clobber (match_scratch 1))]
5010 "reload_completed && !TARGET_DEBUG_D_MODE"
5011 [(const_int 0)]
5012{
5013 mips_set_return_address (operands[0], operands[1]);
5014 DONE;
5015})
5016
5017(define_insn_and_split "exception_receiver"
5018 [(set (reg:SI 28)
5019 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5020 "TARGET_ABICALLS && TARGET_OLDABI"
5021 "#"
5022 "&& reload_completed"
5023 [(const_int 0)]
5024{
5025 mips_restore_gp ();
5026 DONE;
5027}
5028 [(set_attr "type" "load")
5029 (set_attr "length" "12")])
5030
5031;;
5032;; ....................
5033;;
5034;; FUNCTION CALLS
5035;;
5036;; ....................
5037
5038;; Instructions to load a call address from the GOT. The address might
5039;; point to a function or to a lazy binding stub. In the latter case,
5040;; the stub will use the dynamic linker to resolve the function, which
5041;; in turn will change the GOT entry to point to the function's real
5042;; address.
5043;;
5044;; This means that every call, even pure and constant ones, can
5045;; potentially modify the GOT entry. And once a stub has been called,
5046;; we must not call it again.
5047;;
5048;; We represent this restriction using an imaginary fixed register that
5049;; acts like a GOT version number. By making the register call-clobbered,
5050;; we tell the target-independent code that the address could be changed
5051;; by any call insn.
5052(define_insn "load_call<mode>"
5053 [(set (match_operand:P 0 "register_operand" "=c")
5054 (unspec:P [(match_operand:P 1 "register_operand" "r")
5055 (match_operand:P 2 "immediate_operand" "")
5056 (reg:P FAKE_CALL_REGNO)]
5057 UNSPEC_LOAD_CALL))]
5058 "TARGET_ABICALLS"
5059 "<load>\t%0,%R2(%1)"
5060 [(set_attr "type" "load")
5061 (set_attr "mode" "<MODE>")
5062 (set_attr "length" "4")])
5063
5064;; Sibling calls. All these patterns use jump instructions.
5065
5066;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5067;; addresses if a direct jump is acceptable. Since the 'S' constraint
5068;; is defined in terms of call_insn_operand, the same is true of the
5069;; constraints.
5070
5071;; When we use an indirect jump, we need a register that will be
5072;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
5073;; use $25 for this purpose -- and $25 is never clobbered by the
5074;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5075
5076(define_expand "sibcall"
5077 [(parallel [(call (match_operand 0 "")
5078 (match_operand 1 ""))
5079 (use (match_operand 2 "")) ;; next_arg_reg
5080 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5081 "TARGET_SIBCALLS"
5082{
5083 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5084 DONE;
5085})
5086
5087(define_insn "sibcall_internal"
5088 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5089 (match_operand 1 "" ""))]
5090 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5091 { return MIPS_CALL ("j", operands, 0); }
5092 [(set_attr "type" "call")])
5093
5094(define_expand "sibcall_value"
5095 [(parallel [(set (match_operand 0 "")
5096 (call (match_operand 1 "")
5097 (match_operand 2 "")))
5098 (use (match_operand 3 ""))])] ;; next_arg_reg
5099 "TARGET_SIBCALLS"
5100{
5101 mips_expand_call (operands[0], XEXP (operands[1], 0),
5102 operands[2], operands[3], true);
5103 DONE;
5104})
5105
5106(define_insn "sibcall_value_internal"
5107 [(set (match_operand 0 "register_operand" "=df,df")
5108 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5109 (match_operand 2 "" "")))]
5110 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5111 { return MIPS_CALL ("j", operands, 1); }
5112 [(set_attr "type" "call")])
5113
5114(define_insn "sibcall_value_multiple_internal"
5115 [(set (match_operand 0 "register_operand" "=df,df")
5116 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5117 (match_operand 2 "" "")))
5118 (set (match_operand 3 "register_operand" "=df,df")
5119 (call (mem:SI (match_dup 1))
5120 (match_dup 2)))]
5121 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5122 { return MIPS_CALL ("j", operands, 1); }
5123 [(set_attr "type" "call")])
5124
5125(define_expand "call"
5126 [(parallel [(call (match_operand 0 "")
5127 (match_operand 1 ""))
5128 (use (match_operand 2 "")) ;; next_arg_reg
5129 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5130 ""
5131{
5132 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5133 DONE;
5134})
5135
5136;; This instruction directly corresponds to an assembly-language "jal".
5137;; There are four cases:
5138;;
5139;; - -mno-abicalls:
5140;; Both symbolic and register destinations are OK. The pattern
5141;; always expands to a single mips instruction.
5142;;
5143;; - -mabicalls/-mno-explicit-relocs:
5144;; Again, both symbolic and register destinations are OK.
5145;; The call is treated as a multi-instruction black box.
5146;;
5147;; - -mabicalls/-mexplicit-relocs with n32 or n64:
5148;; Only "jal $25" is allowed. This expands to a single "jalr $25"
5149;; instruction.
5150;;
5151;; - -mabicalls/-mexplicit-relocs with o32 or o64:
5152;; Only "jal $25" is allowed. The call is actually two instructions:
5153;; "jalr $25" followed by an insn to reload $gp.
5154;;
5155;; In the last case, we can generate the individual instructions with
5156;; a define_split. There are several things to be wary of:
5157;;
5158;; - We can't expose the load of $gp before reload. If we did,
5159;; it might get removed as dead, but reload can introduce new
5160;; uses of $gp by rematerializing constants.
5161;;
5162;; - We shouldn't restore $gp after calls that never return.
5163;; It isn't valid to insert instructions between a noreturn
5164;; call and the following barrier.
5165;;
5166;; - The splitter deliberately changes the liveness of $gp. The unsplit
5167;; instruction preserves $gp and so have no effect on its liveness.
5168;; But once we generate the separate insns, it becomes obvious that
5169;; $gp is not live on entry to the call.
5170;;
5171;; ??? The operands[2] = insn check is a hack to make the original insn
5172;; available to the splitter.
5173(define_insn_and_split "call_internal"
5174 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5175 (match_operand 1 "" ""))
5176 (clobber (reg:SI 31))]
5177 ""
5178 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5179 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5180 [(const_int 0)]
5181{
5182 emit_call_insn (gen_call_split (operands[0], operands[1]));
5183 if (!find_reg_note (operands[2], REG_NORETURN, 0))
5184 mips_restore_gp ();
5185 DONE;
5186}
5187 [(set_attr "jal" "indirect,direct")
5188 (set_attr "extended_mips16" "no,yes")])
5189
5190(define_insn "call_split"
5191 [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5192 (match_operand 1 "" ""))
5193 (clobber (reg:SI 31))
5194 (clobber (reg:SI 28))]
5195 "TARGET_SPLIT_CALLS"
5196 { return MIPS_CALL ("jal", operands, 0); }
5197 [(set_attr "type" "call")])
5198
5199(define_expand "call_value"
5200 [(parallel [(set (match_operand 0 "")
5201 (call (match_operand 1 "")
5202 (match_operand 2 "")))
5203 (use (match_operand 3 ""))])] ;; next_arg_reg
5204 ""
5205{
5206 mips_expand_call (operands[0], XEXP (operands[1], 0),
5207 operands[2], operands[3], false);
5208 DONE;
5209})
5210
5211;; See comment for call_internal.
5212(define_insn_and_split "call_value_internal"
5213 [(set (match_operand 0 "register_operand" "=df,df")
5214 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5215 (match_operand 2 "" "")))
5216 (clobber (reg:SI 31))]
5217 ""
5218 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5219 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5220 [(const_int 0)]
5221{
5222 emit_call_insn (gen_call_value_split (operands[0], operands[1],
5223 operands[2]));
5224 if (!find_reg_note (operands[3], REG_NORETURN, 0))
5225 mips_restore_gp ();
5226 DONE;
5227}
5228 [(set_attr "jal" "indirect,direct")
5229 (set_attr "extended_mips16" "no,yes")])
5230
5231(define_insn "call_value_split"
5232 [(set (match_operand 0 "register_operand" "=df")
5233 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5234 (match_operand 2 "" "")))
5235 (clobber (reg:SI 31))
5236 (clobber (reg:SI 28))]
5237 "TARGET_SPLIT_CALLS"
5238 { return MIPS_CALL ("jal", operands, 1); }
5239 [(set_attr "type" "call")])
5240
5241;; See comment for call_internal.
5242(define_insn_and_split "call_value_multiple_internal"
5243 [(set (match_operand 0 "register_operand" "=df,df")
5244 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5245 (match_operand 2 "" "")))
5246 (set (match_operand 3 "register_operand" "=df,df")
5247 (call (mem:SI (match_dup 1))
5248 (match_dup 2)))
5249 (clobber (reg:SI 31))]
5250 ""
5251 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5252 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5253 [(const_int 0)]
5254{
5255 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5256 operands[2], operands[3]));
5257 if (!find_reg_note (operands[4], REG_NORETURN, 0))
5258 mips_restore_gp ();
5259 DONE;
5260}
5261 [(set_attr "jal" "indirect,direct")
5262 (set_attr "extended_mips16" "no,yes")])
5263
5264(define_insn "call_value_multiple_split"
5265 [(set (match_operand 0 "register_operand" "=df")
5266 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5267 (match_operand 2 "" "")))
5268 (set (match_operand 3 "register_operand" "=df")
5269 (call (mem:SI (match_dup 1))
5270 (match_dup 2)))
5271 (clobber (reg:SI 31))
5272 (clobber (reg:SI 28))]
5273 "TARGET_SPLIT_CALLS"
5274 { return MIPS_CALL ("jal", operands, 1); }
5275 [(set_attr "type" "call")])
5276
5277;; Call subroutine returning any type.
5278
5279(define_expand "untyped_call"
5280 [(parallel [(call (match_operand 0 "")
5281 (const_int 0))
5282 (match_operand 1 "")
5283 (match_operand 2 "")])]
5284 ""
5285{
5286 int i;
5287
5288 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5289
5290 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5291 {
5292 rtx set = XVECEXP (operands[2], 0, i);
5293 emit_move_insn (SET_DEST (set), SET_SRC (set));
5294 }
5295
5296 emit_insn (gen_blockage ());
5297 DONE;
5298})
5299
5300;;
5301;; ....................
5302;;
5303;; MISC.
5304;;
5305;; ....................
5306;;
5307
5308
5309(define_insn "prefetch"
5310 [(prefetch (match_operand:QI 0 "address_operand" "p")
5311 (match_operand 1 "const_int_operand" "n")
5312 (match_operand 2 "const_int_operand" "n"))]
5313 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5314{
5315 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5316 return "pref\t%1,%a0";
5317}
5318 [(set_attr "type" "prefetch")])
5319
5320(define_insn "*prefetch_indexed_<mode>"
5321 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5322 (match_operand:P 1 "register_operand" "d"))
5323 (match_operand 2 "const_int_operand" "n")
5324 (match_operand 3 "const_int_operand" "n"))]
5325 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5326{
5327 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5328 return "prefx\t%2,%1(%0)";
5329}
5330 [(set_attr "type" "prefetchx")])
5331
5332(define_insn "nop"
5333 [(const_int 0)]
5334 ""
5335 "%(nop%)"
5336 [(set_attr "type" "nop")
5337 (set_attr "mode" "none")])
5338
5339;; Like nop, but commented out when outside a .set noreorder block.
5340(define_insn "hazard_nop"
5341 [(const_int 1)]
5342 ""
5343 {
5344 if (set_noreorder)
5345 return "nop";
5346 else
5347 return "#nop";
5348 }
5349 [(set_attr "type" "nop")])
5350
5351;; MIPS4 Conditional move instructions.
5352
5353(define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5354 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5355 (if_then_else:GPR
5356 (match_operator:MOVECC 4 "equality_operator"
5357 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5358 (const_int 0)])
5359 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5360 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5361 "ISA_HAS_CONDMOVE"
5362 "@
5363 mov%T4\t%0,%z2,%1
5364 mov%t4\t%0,%z3,%1"
5365 [(set_attr "type" "condmove")
5366 (set_attr "mode" "<GPR:MODE>")])
5367
5368(define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5369 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5370 (if_then_else:SCALARF
5371 (match_operator:MOVECC 4 "equality_operator"
5372 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5373 (const_int 0)])
5374 (match_operand:SCALARF 2 "register_operand" "f,0")
5375 (match_operand:SCALARF 3 "register_operand" "0,f")))]
5376 "ISA_HAS_CONDMOVE"
5377 "@
5378 mov%T4.<fmt>\t%0,%2,%1
5379 mov%t4.<fmt>\t%0,%3,%1"
5380 [(set_attr "type" "condmove")
5381 (set_attr "mode" "<SCALARF:MODE>")])
5382
5383;; These are the main define_expand's used to make conditional moves.
5384
5385(define_expand "mov<mode>cc"
5386 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5387 (set (match_operand:GPR 0 "register_operand")
5388 (if_then_else:GPR (match_dup 5)
5389 (match_operand:GPR 2 "reg_or_0_operand")
5390 (match_operand:GPR 3 "reg_or_0_operand")))]
5391 "ISA_HAS_CONDMOVE"
5392{
5393 gen_conditional_move (operands);
5394 DONE;
5395})
5396
5397(define_expand "mov<mode>cc"
5398 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5399 (set (match_operand:SCALARF 0 "register_operand")
5400 (if_then_else:SCALARF (match_dup 5)
5401 (match_operand:SCALARF 2 "register_operand")
5402 (match_operand:SCALARF 3 "register_operand")))]
5403 "ISA_HAS_CONDMOVE"
5404{
5405 gen_conditional_move (operands);
5406 DONE;
5407})
5408
5409;;
5410;; ....................
5411;;
5412;; mips16 inline constant tables
5413;;
5414;; ....................
5415;;
5416
5417(define_insn "consttable_int"
5418 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5419 (match_operand 1 "const_int_operand" "")]
5420 UNSPEC_CONSTTABLE_INT)]
5421 "TARGET_MIPS16"
5422{
5423 assemble_integer (operands[0], INTVAL (operands[1]),
5424 BITS_PER_UNIT * INTVAL (operands[1]), 1);
5425 return "";
5426}
5427 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5428
5429(define_insn "consttable_float"
5430 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5431 UNSPEC_CONSTTABLE_FLOAT)]
5432 "TARGET_MIPS16"
5433{
5434 REAL_VALUE_TYPE d;
5435
5436 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5437 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5438 assemble_real (d, GET_MODE (operands[0]),
5439 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5440 return "";
5441}
5442 [(set (attr "length")
5443 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5444
5445(define_insn "align"
5446 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5447 ""
5448 ".align\t%0"
5449 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5450
5451(define_split
5452 [(match_operand 0 "small_data_pattern")]
5453 "reload_completed"
5454 [(match_dup 0)]
5455 { operands[0] = mips_rewrite_small_data (operands[0]); })
5456
5457; Thread-Local Storage
5458
5459; The TLS base pointer is accessed via "rdhwr $v1, $29". No current
5460; MIPS architecture defines this register, and no current
5461; implementation provides it; instead, any OS which supports TLS is
5462; expected to trap and emulate this instruction. rdhwr is part of the
5463; MIPS 32r2 specification, but we use it on any architecture because
5464; we expect it to be emulated. Use .set to force the assembler to
5465; accept it.
5466
5467(define_insn "tls_get_tp_<mode>"
5468 [(set (match_operand:P 0 "register_operand" "=v")
5469 (unspec:P [(const_int 0)]
5470 UNSPEC_TLS_GET_TP))]
5471 "HAVE_AS_TLS && !TARGET_MIPS16"
5472 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5473 [(set_attr "type" "unknown")
5474 ; Since rdhwr always generates a trap for now, putting it in a delay
5475 ; slot would make the kernel's emulation of it much slower.
5476 (set_attr "can_delay" "no")
5477 (set_attr "mode" "<MODE>")])
5478
5479; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5480
5481(include "mips-ps-3d.md")
5482
5483; The MIPS DSP Instructions.
5484
5485(include "mips-dsp.md")
1046 return "mul\t%0,%1,%2";
1047 return "mult\t%0,%1,%2";
1048}
1049 [(set_attr "type" "imul3,imul")
1050 (set_attr "mode" "SI")])
1051
1052(define_insn "muldi3_mult3"
1053 [(set (match_operand:DI 0 "register_operand" "=d")
1054 (mult:DI (match_operand:DI 1 "register_operand" "d")
1055 (match_operand:DI 2 "register_operand" "d")))
1056 (clobber (match_scratch:DI 3 "=h"))
1057 (clobber (match_scratch:DI 4 "=l"))]
1058 "TARGET_64BIT && GENERATE_MULT3_DI"
1059 "dmult\t%0,%1,%2"
1060 [(set_attr "type" "imul3")
1061 (set_attr "mode" "DI")])
1062
1063;; If a register gets allocated to LO, and we spill to memory, the reload
1064;; will include a move from LO to a GPR. Merge it into the multiplication
1065;; if it can set the GPR directly.
1066;;
1067;; Operand 0: LO
1068;; Operand 1: GPR (1st multiplication operand)
1069;; Operand 2: GPR (2nd multiplication operand)
1070;; Operand 3: HI
1071;; Operand 4: GPR (destination)
1072(define_peephole2
1073 [(parallel
1074 [(set (match_operand:SI 0 "register_operand")
1075 (mult:SI (match_operand:SI 1 "register_operand")
1076 (match_operand:SI 2 "register_operand")))
1077 (clobber (match_operand:SI 3 "register_operand"))
1078 (clobber (scratch:SI))])
1079 (set (match_operand:SI 4 "register_operand")
1080 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1081 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1082 [(parallel
1083 [(set (match_dup 4)
1084 (mult:SI (match_dup 1)
1085 (match_dup 2)))
1086 (clobber (match_dup 3))
1087 (clobber (match_dup 0))])])
1088
1089(define_insn "mul<mode>3_internal"
1090 [(set (match_operand:GPR 0 "register_operand" "=l")
1091 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1092 (match_operand:GPR 2 "register_operand" "d")))
1093 (clobber (match_scratch:GPR 3 "=h"))]
1094 "!TARGET_FIX_R4000"
1095 "<d>mult\t%1,%2"
1096 [(set_attr "type" "imul")
1097 (set_attr "mode" "<MODE>")])
1098
1099(define_insn "mul<mode>3_r4000"
1100 [(set (match_operand:GPR 0 "register_operand" "=d")
1101 (mult:GPR (match_operand:GPR 1 "register_operand" "d")
1102 (match_operand:GPR 2 "register_operand" "d")))
1103 (clobber (match_scratch:GPR 3 "=h"))
1104 (clobber (match_scratch:GPR 4 "=l"))]
1105 "TARGET_FIX_R4000"
1106 "<d>mult\t%1,%2\;mflo\t%0"
1107 [(set_attr "type" "imul")
1108 (set_attr "mode" "<MODE>")
1109 (set_attr "length" "8")])
1110
1111;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1112;; of "mult; mflo". They have the same latency, but the first form gives
1113;; us an extra cycle to compute the operands.
1114
1115;; Operand 0: LO
1116;; Operand 1: GPR (1st multiplication operand)
1117;; Operand 2: GPR (2nd multiplication operand)
1118;; Operand 3: HI
1119;; Operand 4: GPR (destination)
1120(define_peephole2
1121 [(parallel
1122 [(set (match_operand:SI 0 "register_operand")
1123 (mult:SI (match_operand:SI 1 "register_operand")
1124 (match_operand:SI 2 "register_operand")))
1125 (clobber (match_operand:SI 3 "register_operand"))])
1126 (set (match_operand:SI 4 "register_operand")
1127 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1128 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1129 [(set (match_dup 0)
1130 (const_int 0))
1131 (parallel
1132 [(set (match_dup 0)
1133 (plus:SI (mult:SI (match_dup 1)
1134 (match_dup 2))
1135 (match_dup 0)))
1136 (set (match_dup 4)
1137 (plus:SI (mult:SI (match_dup 1)
1138 (match_dup 2))
1139 (match_dup 0)))
1140 (clobber (match_dup 3))])])
1141
1142;; Multiply-accumulate patterns
1143
1144;; For processors that can copy the output to a general register:
1145;;
1146;; The all-d alternative is needed because the combiner will find this
1147;; pattern and then register alloc/reload will move registers around to
1148;; make them fit, and we don't want to trigger unnecessary loads to LO.
1149;;
1150;; The last alternative should be made slightly less desirable, but adding
1151;; "?" to the constraint is too strong, and causes values to be loaded into
1152;; LO even when that's more costly. For now, using "*d" mostly does the
1153;; trick.
1154(define_insn "*mul_acc_si"
1155 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1156 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1157 (match_operand:SI 2 "register_operand" "d,d,d"))
1158 (match_operand:SI 3 "register_operand" "0,l,*d")))
1159 (clobber (match_scratch:SI 4 "=h,h,h"))
1160 (clobber (match_scratch:SI 5 "=X,3,l"))
1161 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1162 "(TARGET_MIPS3900
1163 || ISA_HAS_MADD_MSUB)
1164 && !TARGET_MIPS16"
1165{
1166 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1167 if (which_alternative == 2)
1168 return "#";
1169 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1170 return "#";
1171 return madd[which_alternative];
1172}
1173 [(set_attr "type" "imadd,imadd,multi")
1174 (set_attr "mode" "SI")
1175 (set_attr "length" "4,4,8")])
1176
1177;; Split the above insn if we failed to get LO allocated.
1178(define_split
1179 [(set (match_operand:SI 0 "register_operand")
1180 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1181 (match_operand:SI 2 "register_operand"))
1182 (match_operand:SI 3 "register_operand")))
1183 (clobber (match_scratch:SI 4))
1184 (clobber (match_scratch:SI 5))
1185 (clobber (match_scratch:SI 6))]
1186 "reload_completed && !TARGET_DEBUG_D_MODE
1187 && GP_REG_P (true_regnum (operands[0]))
1188 && GP_REG_P (true_regnum (operands[3]))"
1189 [(parallel [(set (match_dup 6)
1190 (mult:SI (match_dup 1) (match_dup 2)))
1191 (clobber (match_dup 4))
1192 (clobber (match_dup 5))])
1193 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1194 "")
1195
1196;; Splitter to copy result of MADD to a general register
1197(define_split
1198 [(set (match_operand:SI 0 "register_operand")
1199 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1200 (match_operand:SI 2 "register_operand"))
1201 (match_operand:SI 3 "register_operand")))
1202 (clobber (match_scratch:SI 4))
1203 (clobber (match_scratch:SI 5))
1204 (clobber (match_scratch:SI 6))]
1205 "reload_completed && !TARGET_DEBUG_D_MODE
1206 && GP_REG_P (true_regnum (operands[0]))
1207 && true_regnum (operands[3]) == LO_REGNUM"
1208 [(parallel [(set (match_dup 3)
1209 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1210 (match_dup 3)))
1211 (clobber (match_dup 4))
1212 (clobber (match_dup 5))
1213 (clobber (match_dup 6))])
1214 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1215 "")
1216
1217(define_insn "*macc"
1218 [(set (match_operand:SI 0 "register_operand" "=l,d")
1219 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1220 (match_operand:SI 2 "register_operand" "d,d"))
1221 (match_operand:SI 3 "register_operand" "0,l")))
1222 (clobber (match_scratch:SI 4 "=h,h"))
1223 (clobber (match_scratch:SI 5 "=X,3"))]
1224 "ISA_HAS_MACC"
1225{
1226 if (which_alternative == 1)
1227 return "macc\t%0,%1,%2";
1228 else if (TARGET_MIPS5500)
1229 return "madd\t%1,%2";
1230 else
1231 /* The VR4130 assumes that there is a two-cycle latency between a macc
1232 that "writes" to $0 and an instruction that reads from it. We avoid
1233 this by assigning to $1 instead. */
1234 return "%[macc\t%@,%1,%2%]";
1235}
1236 [(set_attr "type" "imadd")
1237 (set_attr "mode" "SI")])
1238
1239(define_insn "*msac"
1240 [(set (match_operand:SI 0 "register_operand" "=l,d")
1241 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1242 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1243 (match_operand:SI 3 "register_operand" "d,d"))))
1244 (clobber (match_scratch:SI 4 "=h,h"))
1245 (clobber (match_scratch:SI 5 "=X,1"))]
1246 "ISA_HAS_MSAC"
1247{
1248 if (which_alternative == 1)
1249 return "msac\t%0,%2,%3";
1250 else if (TARGET_MIPS5500)
1251 return "msub\t%2,%3";
1252 else
1253 return "msac\t$0,%2,%3";
1254}
1255 [(set_attr "type" "imadd")
1256 (set_attr "mode" "SI")])
1257
1258;; An msac-like instruction implemented using negation and a macc.
1259(define_insn_and_split "*msac_using_macc"
1260 [(set (match_operand:SI 0 "register_operand" "=l,d")
1261 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1262 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1263 (match_operand:SI 3 "register_operand" "d,d"))))
1264 (clobber (match_scratch:SI 4 "=h,h"))
1265 (clobber (match_scratch:SI 5 "=X,1"))
1266 (clobber (match_scratch:SI 6 "=d,d"))]
1267 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1268 "#"
1269 "&& reload_completed"
1270 [(set (match_dup 6)
1271 (neg:SI (match_dup 3)))
1272 (parallel
1273 [(set (match_dup 0)
1274 (plus:SI (mult:SI (match_dup 2)
1275 (match_dup 6))
1276 (match_dup 1)))
1277 (clobber (match_dup 4))
1278 (clobber (match_dup 5))])]
1279 ""
1280 [(set_attr "type" "imadd")
1281 (set_attr "length" "8")])
1282
1283;; Patterns generated by the define_peephole2 below.
1284
1285(define_insn "*macc2"
1286 [(set (match_operand:SI 0 "register_operand" "=l")
1287 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1288 (match_operand:SI 2 "register_operand" "d"))
1289 (match_dup 0)))
1290 (set (match_operand:SI 3 "register_operand" "=d")
1291 (plus:SI (mult:SI (match_dup 1)
1292 (match_dup 2))
1293 (match_dup 0)))
1294 (clobber (match_scratch:SI 4 "=h"))]
1295 "ISA_HAS_MACC && reload_completed"
1296 "macc\t%3,%1,%2"
1297 [(set_attr "type" "imadd")
1298 (set_attr "mode" "SI")])
1299
1300(define_insn "*msac2"
1301 [(set (match_operand:SI 0 "register_operand" "=l")
1302 (minus:SI (match_dup 0)
1303 (mult:SI (match_operand:SI 1 "register_operand" "d")
1304 (match_operand:SI 2 "register_operand" "d"))))
1305 (set (match_operand:SI 3 "register_operand" "=d")
1306 (minus:SI (match_dup 0)
1307 (mult:SI (match_dup 1)
1308 (match_dup 2))))
1309 (clobber (match_scratch:SI 4 "=h"))]
1310 "ISA_HAS_MSAC && reload_completed"
1311 "msac\t%3,%1,%2"
1312 [(set_attr "type" "imadd")
1313 (set_attr "mode" "SI")])
1314
1315;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1316;; Similarly msac.
1317;;
1318;; Operand 0: LO
1319;; Operand 1: macc/msac
1320;; Operand 2: HI
1321;; Operand 3: GPR (destination)
1322(define_peephole2
1323 [(parallel
1324 [(set (match_operand:SI 0 "register_operand")
1325 (match_operand:SI 1 "macc_msac_operand"))
1326 (clobber (match_operand:SI 2 "register_operand"))
1327 (clobber (scratch:SI))])
1328 (set (match_operand:SI 3 "register_operand")
1329 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1330 ""
1331 [(parallel [(set (match_dup 0)
1332 (match_dup 1))
1333 (set (match_dup 3)
1334 (match_dup 1))
1335 (clobber (match_dup 2))])]
1336 "")
1337
1338;; When we have a three-address multiplication instruction, it should
1339;; be faster to do a separate multiply and add, rather than moving
1340;; something into LO in order to use a macc instruction.
1341;;
1342;; This peephole needs a scratch register to cater for the case when one
1343;; of the multiplication operands is the same as the destination.
1344;;
1345;; Operand 0: GPR (scratch)
1346;; Operand 1: LO
1347;; Operand 2: GPR (addend)
1348;; Operand 3: GPR (destination)
1349;; Operand 4: macc/msac
1350;; Operand 5: HI
1351;; Operand 6: new multiplication
1352;; Operand 7: new addition/subtraction
1353(define_peephole2
1354 [(match_scratch:SI 0 "d")
1355 (set (match_operand:SI 1 "register_operand")
1356 (match_operand:SI 2 "register_operand"))
1357 (match_dup 0)
1358 (parallel
1359 [(set (match_operand:SI 3 "register_operand")
1360 (match_operand:SI 4 "macc_msac_operand"))
1361 (clobber (match_operand:SI 5 "register_operand"))
1362 (clobber (match_dup 1))])]
1363 "GENERATE_MULT3_SI
1364 && true_regnum (operands[1]) == LO_REGNUM
1365 && peep2_reg_dead_p (2, operands[1])
1366 && GP_REG_P (true_regnum (operands[3]))"
1367 [(parallel [(set (match_dup 0)
1368 (match_dup 6))
1369 (clobber (match_dup 5))
1370 (clobber (match_dup 1))])
1371 (set (match_dup 3)
1372 (match_dup 7))]
1373{
1374 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1375 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1376 operands[2], operands[0]);
1377})
1378
1379;; Same as above, except LO is the initial target of the macc.
1380;;
1381;; Operand 0: GPR (scratch)
1382;; Operand 1: LO
1383;; Operand 2: GPR (addend)
1384;; Operand 3: macc/msac
1385;; Operand 4: HI
1386;; Operand 5: GPR (destination)
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_dup 1)
1396 (match_operand:SI 3 "macc_msac_operand"))
1397 (clobber (match_operand:SI 4 "register_operand"))
1398 (clobber (scratch:SI))])
1399 (match_dup 0)
1400 (set (match_operand:SI 5 "register_operand")
1401 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1402 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1403 [(parallel [(set (match_dup 0)
1404 (match_dup 6))
1405 (clobber (match_dup 4))
1406 (clobber (match_dup 1))])
1407 (set (match_dup 5)
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(define_insn "*mul_sub_si"
1416 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1417 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1418 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1419 (match_operand:SI 3 "register_operand" "d,d,d"))))
1420 (clobber (match_scratch:SI 4 "=h,h,h"))
1421 (clobber (match_scratch:SI 5 "=X,1,l"))
1422 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1423 "ISA_HAS_MADD_MSUB"
1424 "@
1425 msub\t%2,%3
1426 #
1427 #"
1428 [(set_attr "type" "imadd,multi,multi")
1429 (set_attr "mode" "SI")
1430 (set_attr "length" "4,8,8")])
1431
1432;; Split the above insn if we failed to get LO allocated.
1433(define_split
1434 [(set (match_operand:SI 0 "register_operand")
1435 (minus:SI (match_operand:SI 1 "register_operand")
1436 (mult:SI (match_operand:SI 2 "register_operand")
1437 (match_operand:SI 3 "register_operand"))))
1438 (clobber (match_scratch:SI 4))
1439 (clobber (match_scratch:SI 5))
1440 (clobber (match_scratch:SI 6))]
1441 "reload_completed && !TARGET_DEBUG_D_MODE
1442 && GP_REG_P (true_regnum (operands[0]))
1443 && GP_REG_P (true_regnum (operands[1]))"
1444 [(parallel [(set (match_dup 6)
1445 (mult:SI (match_dup 2) (match_dup 3)))
1446 (clobber (match_dup 4))
1447 (clobber (match_dup 5))])
1448 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1449 "")
1450
1451;; Splitter to copy result of MSUB to a general register
1452(define_split
1453 [(set (match_operand:SI 0 "register_operand")
1454 (minus:SI (match_operand:SI 1 "register_operand")
1455 (mult:SI (match_operand:SI 2 "register_operand")
1456 (match_operand:SI 3 "register_operand"))))
1457 (clobber (match_scratch:SI 4))
1458 (clobber (match_scratch:SI 5))
1459 (clobber (match_scratch:SI 6))]
1460 "reload_completed && !TARGET_DEBUG_D_MODE
1461 && GP_REG_P (true_regnum (operands[0]))
1462 && true_regnum (operands[1]) == LO_REGNUM"
1463 [(parallel [(set (match_dup 1)
1464 (minus:SI (match_dup 1)
1465 (mult:SI (match_dup 2) (match_dup 3))))
1466 (clobber (match_dup 4))
1467 (clobber (match_dup 5))
1468 (clobber (match_dup 6))])
1469 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1470 "")
1471
1472(define_insn "*muls"
1473 [(set (match_operand:SI 0 "register_operand" "=l,d")
1474 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1475 (match_operand:SI 2 "register_operand" "d,d"))))
1476 (clobber (match_scratch:SI 3 "=h,h"))
1477 (clobber (match_scratch:SI 4 "=X,l"))]
1478 "ISA_HAS_MULS"
1479 "@
1480 muls\t$0,%1,%2
1481 muls\t%0,%1,%2"
1482 [(set_attr "type" "imul,imul3")
1483 (set_attr "mode" "SI")])
1484
1485;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1486
1487(define_expand "<u>mulsidi3"
1488 [(parallel
1489 [(set (match_operand:DI 0 "register_operand")
1490 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1491 (any_extend:DI (match_operand:SI 2 "register_operand"))))
1492 (clobber (scratch:DI))
1493 (clobber (scratch:DI))
1494 (clobber (scratch:DI))])]
1495 "!TARGET_64BIT || !TARGET_FIX_R4000"
1496{
1497 if (!TARGET_64BIT)
1498 {
1499 if (!TARGET_FIX_R4000)
1500 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1501 operands[2]));
1502 else
1503 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1504 operands[2]));
1505 DONE;
1506 }
1507})
1508
1509(define_insn "<u>mulsidi3_32bit_internal"
1510 [(set (match_operand:DI 0 "register_operand" "=x")
1511 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1512 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1513 "!TARGET_64BIT && !TARGET_FIX_R4000"
1514 "mult<u>\t%1,%2"
1515 [(set_attr "type" "imul")
1516 (set_attr "mode" "SI")])
1517
1518(define_insn "<u>mulsidi3_32bit_r4000"
1519 [(set (match_operand:DI 0 "register_operand" "=d")
1520 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1521 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1522 (clobber (match_scratch:DI 3 "=x"))]
1523 "!TARGET_64BIT && TARGET_FIX_R4000"
1524 "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1525 [(set_attr "type" "imul")
1526 (set_attr "mode" "SI")
1527 (set_attr "length" "12")])
1528
1529(define_insn_and_split "*<u>mulsidi3_64bit"
1530 [(set (match_operand:DI 0 "register_operand" "=d")
1531 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1532 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1533 (clobber (match_scratch:DI 3 "=l"))
1534 (clobber (match_scratch:DI 4 "=h"))
1535 (clobber (match_scratch:DI 5 "=d"))]
1536 "TARGET_64BIT && !TARGET_FIX_R4000"
1537 "#"
1538 "&& reload_completed"
1539 [(parallel
1540 [(set (match_dup 3)
1541 (sign_extend:DI
1542 (mult:SI (match_dup 1)
1543 (match_dup 2))))
1544 (set (match_dup 4)
1545 (ashiftrt:DI
1546 (mult:DI (any_extend:DI (match_dup 1))
1547 (any_extend:DI (match_dup 2)))
1548 (const_int 32)))])
1549
1550 ;; OP5 <- LO, OP0 <- HI
1551 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1552 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1553
1554 ;; Zero-extend OP5.
1555 (set (match_dup 5)
1556 (ashift:DI (match_dup 5)
1557 (const_int 32)))
1558 (set (match_dup 5)
1559 (lshiftrt:DI (match_dup 5)
1560 (const_int 32)))
1561
1562 ;; Shift OP0 into place.
1563 (set (match_dup 0)
1564 (ashift:DI (match_dup 0)
1565 (const_int 32)))
1566
1567 ;; OR the two halves together
1568 (set (match_dup 0)
1569 (ior:DI (match_dup 0)
1570 (match_dup 5)))]
1571 ""
1572 [(set_attr "type" "imul")
1573 (set_attr "mode" "SI")
1574 (set_attr "length" "24")])
1575
1576(define_insn "*<u>mulsidi3_64bit_parts"
1577 [(set (match_operand:DI 0 "register_operand" "=l")
1578 (sign_extend:DI
1579 (mult:SI (match_operand:SI 2 "register_operand" "d")
1580 (match_operand:SI 3 "register_operand" "d"))))
1581 (set (match_operand:DI 1 "register_operand" "=h")
1582 (ashiftrt:DI
1583 (mult:DI (any_extend:DI (match_dup 2))
1584 (any_extend:DI (match_dup 3)))
1585 (const_int 32)))]
1586 "TARGET_64BIT && !TARGET_FIX_R4000"
1587 "mult<u>\t%2,%3"
1588 [(set_attr "type" "imul")
1589 (set_attr "mode" "SI")])
1590
1591;; Widening multiply with negation.
1592(define_insn "*muls<u>_di"
1593 [(set (match_operand:DI 0 "register_operand" "=x")
1594 (neg:DI
1595 (mult:DI
1596 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1597 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1598 "!TARGET_64BIT && ISA_HAS_MULS"
1599 "muls<u>\t$0,%1,%2"
1600 [(set_attr "type" "imul")
1601 (set_attr "mode" "SI")])
1602
1603(define_insn "*msac<u>_di"
1604 [(set (match_operand:DI 0 "register_operand" "=x")
1605 (minus:DI
1606 (match_operand:DI 3 "register_operand" "0")
1607 (mult:DI
1608 (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1609 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1610 "!TARGET_64BIT && ISA_HAS_MSAC"
1611{
1612 if (TARGET_MIPS5500)
1613 return "msub<u>\t%1,%2";
1614 else
1615 return "msac<u>\t$0,%1,%2";
1616}
1617 [(set_attr "type" "imadd")
1618 (set_attr "mode" "SI")])
1619
1620;; _highpart patterns
1621
1622(define_expand "<su>mulsi3_highpart"
1623 [(set (match_operand:SI 0 "register_operand")
1624 (truncate:SI
1625 (lshiftrt:DI
1626 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1627 (any_extend:DI (match_operand:SI 2 "register_operand")))
1628 (const_int 32))))]
1629 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1630{
1631 if (ISA_HAS_MULHI)
1632 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1633 operands[1],
1634 operands[2]));
1635 else
1636 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1637 operands[2]));
1638 DONE;
1639})
1640
1641(define_insn "<su>mulsi3_highpart_internal"
1642 [(set (match_operand:SI 0 "register_operand" "=h")
1643 (truncate:SI
1644 (lshiftrt:DI
1645 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1646 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1647 (const_int 32))))
1648 (clobber (match_scratch:SI 3 "=l"))]
1649 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1650 "mult<u>\t%1,%2"
1651 [(set_attr "type" "imul")
1652 (set_attr "mode" "SI")])
1653
1654(define_insn "<su>mulsi3_highpart_mulhi_internal"
1655 [(set (match_operand:SI 0 "register_operand" "=h,d")
1656 (truncate:SI
1657 (lshiftrt:DI
1658 (mult:DI
1659 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1660 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1661 (const_int 32))))
1662 (clobber (match_scratch:SI 3 "=l,l"))
1663 (clobber (match_scratch:SI 4 "=X,h"))]
1664 "ISA_HAS_MULHI"
1665 "@
1666 mult<u>\t%1,%2
1667 mulhi<u>\t%0,%1,%2"
1668 [(set_attr "type" "imul,imul3")
1669 (set_attr "mode" "SI")])
1670
1671(define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1672 [(set (match_operand:SI 0 "register_operand" "=h,d")
1673 (truncate:SI
1674 (lshiftrt:DI
1675 (neg:DI
1676 (mult:DI
1677 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1678 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1679 (const_int 32))))
1680 (clobber (match_scratch:SI 3 "=l,l"))
1681 (clobber (match_scratch:SI 4 "=X,h"))]
1682 "ISA_HAS_MULHI"
1683 "@
1684 mulshi<u>\t%.,%1,%2
1685 mulshi<u>\t%0,%1,%2"
1686 [(set_attr "type" "imul,imul3")
1687 (set_attr "mode" "SI")])
1688
1689;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120
1690;; errata MD(0), which says that dmultu does not always produce the
1691;; correct result.
1692(define_insn "<su>muldi3_highpart"
1693 [(set (match_operand:DI 0 "register_operand" "=h")
1694 (truncate:DI
1695 (lshiftrt:TI
1696 (mult:TI
1697 (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1698 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1699 (const_int 64))))
1700 (clobber (match_scratch:DI 3 "=l"))]
1701 "TARGET_64BIT && !TARGET_FIX_R4000
1702 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1703 "dmult<u>\t%1,%2"
1704 [(set_attr "type" "imul")
1705 (set_attr "mode" "DI")])
1706
1707;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1708;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1709
1710(define_insn "madsi"
1711 [(set (match_operand:SI 0 "register_operand" "+l")
1712 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1713 (match_operand:SI 2 "register_operand" "d"))
1714 (match_dup 0)))
1715 (clobber (match_scratch:SI 3 "=h"))]
1716 "TARGET_MAD"
1717 "mad\t%1,%2"
1718 [(set_attr "type" "imadd")
1719 (set_attr "mode" "SI")])
1720
1721(define_insn "*<su>mul_acc_di"
1722 [(set (match_operand:DI 0 "register_operand" "=x")
1723 (plus:DI
1724 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1725 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1726 (match_operand:DI 3 "register_operand" "0")))]
1727 "(TARGET_MAD || ISA_HAS_MACC)
1728 && !TARGET_64BIT"
1729{
1730 if (TARGET_MAD)
1731 return "mad<u>\t%1,%2";
1732 else if (TARGET_MIPS5500)
1733 return "madd<u>\t%1,%2";
1734 else
1735 /* See comment in *macc. */
1736 return "%[macc<u>\t%@,%1,%2%]";
1737}
1738 [(set_attr "type" "imadd")
1739 (set_attr "mode" "SI")])
1740
1741;; Floating point multiply accumulate instructions.
1742
1743(define_insn "*madd<mode>"
1744 [(set (match_operand:ANYF 0 "register_operand" "=f")
1745 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1746 (match_operand:ANYF 2 "register_operand" "f"))
1747 (match_operand:ANYF 3 "register_operand" "f")))]
1748 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1749 "madd.<fmt>\t%0,%3,%1,%2"
1750 [(set_attr "type" "fmadd")
1751 (set_attr "mode" "<UNITMODE>")])
1752
1753(define_insn "*msub<mode>"
1754 [(set (match_operand:ANYF 0 "register_operand" "=f")
1755 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1756 (match_operand:ANYF 2 "register_operand" "f"))
1757 (match_operand:ANYF 3 "register_operand" "f")))]
1758 "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1759 "msub.<fmt>\t%0,%3,%1,%2"
1760 [(set_attr "type" "fmadd")
1761 (set_attr "mode" "<UNITMODE>")])
1762
1763(define_insn "*nmadd<mode>"
1764 [(set (match_operand:ANYF 0 "register_operand" "=f")
1765 (neg:ANYF (plus:ANYF
1766 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1767 (match_operand:ANYF 2 "register_operand" "f"))
1768 (match_operand:ANYF 3 "register_operand" "f"))))]
1769 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1770 && HONOR_SIGNED_ZEROS (<MODE>mode)
1771 && !HONOR_NANS (<MODE>mode)"
1772 "nmadd.<fmt>\t%0,%3,%1,%2"
1773 [(set_attr "type" "fmadd")
1774 (set_attr "mode" "<UNITMODE>")])
1775
1776(define_insn "*nmadd<mode>_fastmath"
1777 [(set (match_operand:ANYF 0 "register_operand" "=f")
1778 (minus:ANYF
1779 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1780 (match_operand:ANYF 2 "register_operand" "f"))
1781 (match_operand:ANYF 3 "register_operand" "f")))]
1782 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1783 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1784 && !HONOR_NANS (<MODE>mode)"
1785 "nmadd.<fmt>\t%0,%3,%1,%2"
1786 [(set_attr "type" "fmadd")
1787 (set_attr "mode" "<UNITMODE>")])
1788
1789(define_insn "*nmsub<mode>"
1790 [(set (match_operand:ANYF 0 "register_operand" "=f")
1791 (neg:ANYF (minus:ANYF
1792 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1793 (match_operand:ANYF 3 "register_operand" "f"))
1794 (match_operand:ANYF 1 "register_operand" "f"))))]
1795 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1796 && HONOR_SIGNED_ZEROS (<MODE>mode)
1797 && !HONOR_NANS (<MODE>mode)"
1798 "nmsub.<fmt>\t%0,%1,%2,%3"
1799 [(set_attr "type" "fmadd")
1800 (set_attr "mode" "<UNITMODE>")])
1801
1802(define_insn "*nmsub<mode>_fastmath"
1803 [(set (match_operand:ANYF 0 "register_operand" "=f")
1804 (minus:ANYF
1805 (match_operand:ANYF 1 "register_operand" "f")
1806 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1807 (match_operand:ANYF 3 "register_operand" "f"))))]
1808 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1809 && !HONOR_SIGNED_ZEROS (<MODE>mode)
1810 && !HONOR_NANS (<MODE>mode)"
1811 "nmsub.<fmt>\t%0,%1,%2,%3"
1812 [(set_attr "type" "fmadd")
1813 (set_attr "mode" "<UNITMODE>")])
1814
1815;;
1816;; ....................
1817;;
1818;; DIVISION and REMAINDER
1819;;
1820;; ....................
1821;;
1822
1823(define_expand "div<mode>3"
1824 [(set (match_operand:ANYF 0 "register_operand")
1825 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
1826 (match_operand:ANYF 2 "register_operand")))]
1827 "<divide_condition>"
1828{
1829 if (const_1_operand (operands[1], <MODE>mode))
1830 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1831 operands[1] = force_reg (<MODE>mode, operands[1]);
1832})
1833
1834;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1835;;
1836;; If an mfc1 or dmfc1 happens to access the floating point register
1837;; file at the same time a long latency operation (div, sqrt, recip,
1838;; sqrt) iterates an intermediate result back through the floating
1839;; point register file bypass, then instead returning the correct
1840;; register value the mfc1 or dmfc1 operation returns the intermediate
1841;; result of the long latency operation.
1842;;
1843;; The workaround is to insert an unconditional 'mov' from/to the
1844;; long latency op destination register.
1845
1846(define_insn "*div<mode>3"
1847 [(set (match_operand:ANYF 0 "register_operand" "=f")
1848 (div:ANYF (match_operand:ANYF 1 "register_operand" "f")
1849 (match_operand:ANYF 2 "register_operand" "f")))]
1850 "<divide_condition>"
1851{
1852 if (TARGET_FIX_SB1)
1853 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1854 else
1855 return "div.<fmt>\t%0,%1,%2";
1856}
1857 [(set_attr "type" "fdiv")
1858 (set_attr "mode" "<UNITMODE>")
1859 (set (attr "length")
1860 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1861 (const_int 8)
1862 (const_int 4)))])
1863
1864(define_insn "*recip<mode>3"
1865 [(set (match_operand:ANYF 0 "register_operand" "=f")
1866 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1867 (match_operand:ANYF 2 "register_operand" "f")))]
1868 "<recip_condition> && flag_unsafe_math_optimizations"
1869{
1870 if (TARGET_FIX_SB1)
1871 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1872 else
1873 return "recip.<fmt>\t%0,%2";
1874}
1875 [(set_attr "type" "frdiv")
1876 (set_attr "mode" "<UNITMODE>")
1877 (set (attr "length")
1878 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1879 (const_int 8)
1880 (const_int 4)))])
1881
1882;; VR4120 errata MD(A1): signed division instructions do not work correctly
1883;; with negative operands. We use special libgcc functions instead.
1884(define_insn "divmod<mode>4"
1885 [(set (match_operand:GPR 0 "register_operand" "=l")
1886 (div:GPR (match_operand:GPR 1 "register_operand" "d")
1887 (match_operand:GPR 2 "register_operand" "d")))
1888 (set (match_operand:GPR 3 "register_operand" "=h")
1889 (mod:GPR (match_dup 1)
1890 (match_dup 2)))]
1891 "!TARGET_FIX_VR4120"
1892 { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1893 [(set_attr "type" "idiv")
1894 (set_attr "mode" "<MODE>")])
1895
1896(define_insn "udivmod<mode>4"
1897 [(set (match_operand:GPR 0 "register_operand" "=l")
1898 (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1899 (match_operand:GPR 2 "register_operand" "d")))
1900 (set (match_operand:GPR 3 "register_operand" "=h")
1901 (umod:GPR (match_dup 1)
1902 (match_dup 2)))]
1903 ""
1904 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1905 [(set_attr "type" "idiv")
1906 (set_attr "mode" "<MODE>")])
1907
1908;;
1909;; ....................
1910;;
1911;; SQUARE ROOT
1912;;
1913;; ....................
1914
1915;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1916;; "*div[sd]f3" comment for details).
1917
1918(define_insn "sqrt<mode>2"
1919 [(set (match_operand:ANYF 0 "register_operand" "=f")
1920 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1921 "<sqrt_condition>"
1922{
1923 if (TARGET_FIX_SB1)
1924 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1925 else
1926 return "sqrt.<fmt>\t%0,%1";
1927}
1928 [(set_attr "type" "fsqrt")
1929 (set_attr "mode" "<UNITMODE>")
1930 (set (attr "length")
1931 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1932 (const_int 8)
1933 (const_int 4)))])
1934
1935(define_insn "*rsqrt<mode>a"
1936 [(set (match_operand:ANYF 0 "register_operand" "=f")
1937 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1938 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
1939 "<recip_condition> && flag_unsafe_math_optimizations"
1940{
1941 if (TARGET_FIX_SB1)
1942 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1943 else
1944 return "rsqrt.<fmt>\t%0,%2";
1945}
1946 [(set_attr "type" "frsqrt")
1947 (set_attr "mode" "<UNITMODE>")
1948 (set (attr "length")
1949 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1950 (const_int 8)
1951 (const_int 4)))])
1952
1953(define_insn "*rsqrt<mode>b"
1954 [(set (match_operand:ANYF 0 "register_operand" "=f")
1955 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
1956 (match_operand:ANYF 2 "register_operand" "f"))))]
1957 "<recip_condition> && flag_unsafe_math_optimizations"
1958{
1959 if (TARGET_FIX_SB1)
1960 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1961 else
1962 return "rsqrt.<fmt>\t%0,%2";
1963}
1964 [(set_attr "type" "frsqrt")
1965 (set_attr "mode" "<UNITMODE>")
1966 (set (attr "length")
1967 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1968 (const_int 8)
1969 (const_int 4)))])
1970
1971;;
1972;; ....................
1973;;
1974;; ABSOLUTE VALUE
1975;;
1976;; ....................
1977
1978;; Do not use the integer abs macro instruction, since that signals an
1979;; exception on -2147483648 (sigh).
1980
1981;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
1982;; invalid; it does not clear their sign bits. We therefore can't use
1983;; abs.fmt if the signs of NaNs matter.
1984
1985(define_insn "abs<mode>2"
1986 [(set (match_operand:ANYF 0 "register_operand" "=f")
1987 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1988 "!HONOR_NANS (<MODE>mode)"
1989 "abs.<fmt>\t%0,%1"
1990 [(set_attr "type" "fabs")
1991 (set_attr "mode" "<UNITMODE>")])
1992
1993;;
1994;; ...................
1995;;
1996;; Count leading zeroes.
1997;;
1998;; ...................
1999;;
2000
2001(define_insn "clz<mode>2"
2002 [(set (match_operand:GPR 0 "register_operand" "=d")
2003 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
2004 "ISA_HAS_CLZ_CLO"
2005 "<d>clz\t%0,%1"
2006 [(set_attr "type" "clz")
2007 (set_attr "mode" "<MODE>")])
2008
2009;;
2010;; ....................
2011;;
2012;; NEGATION and ONE'S COMPLEMENT
2013;;
2014;; ....................
2015
2016(define_insn "negsi2"
2017 [(set (match_operand:SI 0 "register_operand" "=d")
2018 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2019 ""
2020{
2021 if (TARGET_MIPS16)
2022 return "neg\t%0,%1";
2023 else
2024 return "subu\t%0,%.,%1";
2025}
2026 [(set_attr "type" "arith")
2027 (set_attr "mode" "SI")])
2028
2029(define_insn "negdi2"
2030 [(set (match_operand:DI 0 "register_operand" "=d")
2031 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2032 "TARGET_64BIT && !TARGET_MIPS16"
2033 "dsubu\t%0,%.,%1"
2034 [(set_attr "type" "arith")
2035 (set_attr "mode" "DI")])
2036
2037;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
2038;; invalid; it does not flip their sign bit. We therefore can't use
2039;; neg.fmt if the signs of NaNs matter.
2040
2041(define_insn "neg<mode>2"
2042 [(set (match_operand:ANYF 0 "register_operand" "=f")
2043 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
2044 "!HONOR_NANS (<MODE>mode)"
2045 "neg.<fmt>\t%0,%1"
2046 [(set_attr "type" "fneg")
2047 (set_attr "mode" "<UNITMODE>")])
2048
2049(define_insn "one_cmpl<mode>2"
2050 [(set (match_operand:GPR 0 "register_operand" "=d")
2051 (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
2052 ""
2053{
2054 if (TARGET_MIPS16)
2055 return "not\t%0,%1";
2056 else
2057 return "nor\t%0,%.,%1";
2058}
2059 [(set_attr "type" "arith")
2060 (set_attr "mode" "<MODE>")])
2061
2062;;
2063;; ....................
2064;;
2065;; LOGICAL
2066;;
2067;; ....................
2068;;
2069
2070;; Many of these instructions use trivial define_expands, because we
2071;; want to use a different set of constraints when TARGET_MIPS16.
2072
2073(define_expand "and<mode>3"
2074 [(set (match_operand:GPR 0 "register_operand")
2075 (and:GPR (match_operand:GPR 1 "register_operand")
2076 (match_operand:GPR 2 "uns_arith_operand")))]
2077 ""
2078{
2079 if (TARGET_MIPS16)
2080 operands[2] = force_reg (<MODE>mode, operands[2]);
2081})
2082
2083(define_insn "*and<mode>3"
2084 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2085 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2086 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2087 "!TARGET_MIPS16"
2088 "@
2089 and\t%0,%1,%2
2090 andi\t%0,%1,%x2"
2091 [(set_attr "type" "arith")
2092 (set_attr "mode" "<MODE>")])
2093
2094(define_insn "*and<mode>3_mips16"
2095 [(set (match_operand:GPR 0 "register_operand" "=d")
2096 (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2097 (match_operand:GPR 2 "register_operand" "d")))]
2098 "TARGET_MIPS16"
2099 "and\t%0,%2"
2100 [(set_attr "type" "arith")
2101 (set_attr "mode" "<MODE>")])
2102
2103(define_expand "ior<mode>3"
2104 [(set (match_operand:GPR 0 "register_operand")
2105 (ior:GPR (match_operand:GPR 1 "register_operand")
2106 (match_operand:GPR 2 "uns_arith_operand")))]
2107 ""
2108{
2109 if (TARGET_MIPS16)
2110 operands[2] = force_reg (<MODE>mode, operands[2]);
2111})
2112
2113(define_insn "*ior<mode>3"
2114 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2115 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2116 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2117 "!TARGET_MIPS16"
2118 "@
2119 or\t%0,%1,%2
2120 ori\t%0,%1,%x2"
2121 [(set_attr "type" "arith")
2122 (set_attr "mode" "<MODE>")])
2123
2124(define_insn "*ior<mode>3_mips16"
2125 [(set (match_operand:GPR 0 "register_operand" "=d")
2126 (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2127 (match_operand:GPR 2 "register_operand" "d")))]
2128 "TARGET_MIPS16"
2129 "or\t%0,%2"
2130 [(set_attr "type" "arith")
2131 (set_attr "mode" "<MODE>")])
2132
2133(define_expand "xor<mode>3"
2134 [(set (match_operand:GPR 0 "register_operand")
2135 (xor:GPR (match_operand:GPR 1 "register_operand")
2136 (match_operand:GPR 2 "uns_arith_operand")))]
2137 ""
2138 "")
2139
2140(define_insn ""
2141 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2142 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2143 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2144 "!TARGET_MIPS16"
2145 "@
2146 xor\t%0,%1,%2
2147 xori\t%0,%1,%x2"
2148 [(set_attr "type" "arith")
2149 (set_attr "mode" "<MODE>")])
2150
2151(define_insn ""
2152 [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2153 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2154 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2155 "TARGET_MIPS16"
2156 "@
2157 xor\t%0,%2
2158 cmpi\t%1,%2
2159 cmp\t%1,%2"
2160 [(set_attr "type" "arith")
2161 (set_attr "mode" "<MODE>")
2162 (set_attr_alternative "length"
2163 [(const_int 4)
2164 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2165 (const_int 4)
2166 (const_int 8))
2167 (const_int 4)])])
2168
2169(define_insn "*nor<mode>3"
2170 [(set (match_operand:GPR 0 "register_operand" "=d")
2171 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2172 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2173 "!TARGET_MIPS16"
2174 "nor\t%0,%1,%2"
2175 [(set_attr "type" "arith")
2176 (set_attr "mode" "<MODE>")])
2177
2178;;
2179;; ....................
2180;;
2181;; TRUNCATION
2182;;
2183;; ....................
2184
2185
2186
2187(define_insn "truncdfsf2"
2188 [(set (match_operand:SF 0 "register_operand" "=f")
2189 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2190 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2191 "cvt.s.d\t%0,%1"
2192 [(set_attr "type" "fcvt")
2193 (set_attr "cnv_mode" "D2S")
2194 (set_attr "mode" "SF")])
2195
2196;; Integer truncation patterns. Truncating SImode values to smaller
2197;; modes is a no-op, as it is for most other GCC ports. Truncating
2198;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2199;; need to make sure that the lower 32 bits are properly sign-extended
2200;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2201;; smaller than SImode is equivalent to two separate truncations:
2202;;
2203;; A B
2204;; DI ---> HI == DI ---> SI ---> HI
2205;; DI ---> QI == DI ---> SI ---> QI
2206;;
2207;; Step A needs a real instruction but step B does not.
2208
2209(define_insn "truncdisi2"
2210 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2211 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2212 "TARGET_64BIT"
2213 "@
2214 sll\t%0,%1,0
2215 sw\t%1,%0"
2216 [(set_attr "type" "shift,store")
2217 (set_attr "mode" "SI")
2218 (set_attr "extended_mips16" "yes,*")])
2219
2220(define_insn "truncdihi2"
2221 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2222 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2223 "TARGET_64BIT"
2224 "@
2225 sll\t%0,%1,0
2226 sh\t%1,%0"
2227 [(set_attr "type" "shift,store")
2228 (set_attr "mode" "SI")
2229 (set_attr "extended_mips16" "yes,*")])
2230
2231(define_insn "truncdiqi2"
2232 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2233 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2234 "TARGET_64BIT"
2235 "@
2236 sll\t%0,%1,0
2237 sb\t%1,%0"
2238 [(set_attr "type" "shift,store")
2239 (set_attr "mode" "SI")
2240 (set_attr "extended_mips16" "yes,*")])
2241
2242;; Combiner patterns to optimize shift/truncate combinations.
2243
2244(define_insn ""
2245 [(set (match_operand:SI 0 "register_operand" "=d")
2246 (truncate:SI
2247 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2248 (match_operand:DI 2 "const_arith_operand" ""))))]
2249 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2250 "dsra\t%0,%1,%2"
2251 [(set_attr "type" "shift")
2252 (set_attr "mode" "SI")])
2253
2254(define_insn ""
2255 [(set (match_operand:SI 0 "register_operand" "=d")
2256 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2257 (const_int 32))))]
2258 "TARGET_64BIT && !TARGET_MIPS16"
2259 "dsra\t%0,%1,32"
2260 [(set_attr "type" "shift")
2261 (set_attr "mode" "SI")])
2262
2263
2264;; Combiner patterns for truncate/sign_extend combinations. They use
2265;; the shift/truncate patterns above.
2266
2267(define_insn_and_split ""
2268 [(set (match_operand:SI 0 "register_operand" "=d")
2269 (sign_extend:SI
2270 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2271 "TARGET_64BIT && !TARGET_MIPS16"
2272 "#"
2273 "&& reload_completed"
2274 [(set (match_dup 2)
2275 (ashift:DI (match_dup 1)
2276 (const_int 48)))
2277 (set (match_dup 0)
2278 (truncate:SI (ashiftrt:DI (match_dup 2)
2279 (const_int 48))))]
2280 { operands[2] = gen_lowpart (DImode, operands[0]); })
2281
2282(define_insn_and_split ""
2283 [(set (match_operand:SI 0 "register_operand" "=d")
2284 (sign_extend:SI
2285 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2286 "TARGET_64BIT && !TARGET_MIPS16"
2287 "#"
2288 "&& reload_completed"
2289 [(set (match_dup 2)
2290 (ashift:DI (match_dup 1)
2291 (const_int 56)))
2292 (set (match_dup 0)
2293 (truncate:SI (ashiftrt:DI (match_dup 2)
2294 (const_int 56))))]
2295 { operands[2] = gen_lowpart (DImode, operands[0]); })
2296
2297
2298;; Combiner patterns to optimize truncate/zero_extend combinations.
2299
2300(define_insn ""
2301 [(set (match_operand:SI 0 "register_operand" "=d")
2302 (zero_extend:SI (truncate:HI
2303 (match_operand:DI 1 "register_operand" "d"))))]
2304 "TARGET_64BIT && !TARGET_MIPS16"
2305 "andi\t%0,%1,0xffff"
2306 [(set_attr "type" "arith")
2307 (set_attr "mode" "SI")])
2308
2309(define_insn ""
2310 [(set (match_operand:SI 0 "register_operand" "=d")
2311 (zero_extend:SI (truncate:QI
2312 (match_operand:DI 1 "register_operand" "d"))))]
2313 "TARGET_64BIT && !TARGET_MIPS16"
2314 "andi\t%0,%1,0xff"
2315 [(set_attr "type" "arith")
2316 (set_attr "mode" "SI")])
2317
2318(define_insn ""
2319 [(set (match_operand:HI 0 "register_operand" "=d")
2320 (zero_extend:HI (truncate:QI
2321 (match_operand:DI 1 "register_operand" "d"))))]
2322 "TARGET_64BIT && !TARGET_MIPS16"
2323 "andi\t%0,%1,0xff"
2324 [(set_attr "type" "arith")
2325 (set_attr "mode" "HI")])
2326
2327;;
2328;; ....................
2329;;
2330;; ZERO EXTENSION
2331;;
2332;; ....................
2333
2334;; Extension insns.
2335
2336(define_insn_and_split "zero_extendsidi2"
2337 [(set (match_operand:DI 0 "register_operand" "=d,d")
2338 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
2339 "TARGET_64BIT"
2340 "@
2341 #
2342 lwu\t%0,%1"
2343 "&& reload_completed && REG_P (operands[1])"
2344 [(set (match_dup 0)
2345 (ashift:DI (match_dup 1) (const_int 32)))
2346 (set (match_dup 0)
2347 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2348 { operands[1] = gen_lowpart (DImode, operands[1]); }
2349 [(set_attr "type" "multi,load")
2350 (set_attr "mode" "DI")
2351 (set_attr "length" "8,*")])
2352
2353;; Combine is not allowed to convert this insn into a zero_extendsidi2
2354;; because of TRULY_NOOP_TRUNCATION.
2355
2356(define_insn_and_split "*clear_upper32"
2357 [(set (match_operand:DI 0 "register_operand" "=d,d")
2358 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2359 (const_int 4294967295)))]
2360 "TARGET_64BIT"
2361{
2362 if (which_alternative == 0)
2363 return "#";
2364
2365 operands[1] = gen_lowpart (SImode, operands[1]);
2366 return "lwu\t%0,%1";
2367}
2368 "&& reload_completed && REG_P (operands[1])"
2369 [(set (match_dup 0)
2370 (ashift:DI (match_dup 1) (const_int 32)))
2371 (set (match_dup 0)
2372 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2373 ""
2374 [(set_attr "type" "multi,load")
2375 (set_attr "mode" "DI")
2376 (set_attr "length" "8,*")])
2377
2378(define_expand "zero_extend<SHORT:mode><GPR:mode>2"
2379 [(set (match_operand:GPR 0 "register_operand")
2380 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2381 ""
2382{
2383 if (TARGET_MIPS16 && !GENERATE_MIPS16E
2384 && !memory_operand (operands[1], <SHORT:MODE>mode))
2385 {
2386 emit_insn (gen_and<GPR:mode>3 (operands[0],
2387 gen_lowpart (<GPR:MODE>mode, operands[1]),
2388 force_reg (<GPR:MODE>mode,
2389 GEN_INT (<SHORT:mask>))));
2390 DONE;
2391 }
2392})
2393
2394(define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
2395 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2396 (zero_extend:GPR
2397 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2398 "!TARGET_MIPS16"
2399 "@
2400 andi\t%0,%1,<SHORT:mask>
2401 l<SHORT:size>u\t%0,%1"
2402 [(set_attr "type" "arith,load")
2403 (set_attr "mode" "<GPR:MODE>")])
2404
2405(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
2406 [(set (match_operand:GPR 0 "register_operand" "=d")
2407 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))]
2408 "GENERATE_MIPS16E"
2409 "ze<SHORT:size>\t%0"
2410 [(set_attr "type" "arith")
2411 (set_attr "mode" "<GPR:MODE>")])
2412
2413(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16"
2414 [(set (match_operand:GPR 0 "register_operand" "=d")
2415 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))]
2416 "TARGET_MIPS16"
2417 "l<SHORT:size>u\t%0,%1"
2418 [(set_attr "type" "load")
2419 (set_attr "mode" "<GPR:MODE>")])
2420
2421(define_expand "zero_extendqihi2"
2422 [(set (match_operand:HI 0 "register_operand")
2423 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2424 ""
2425{
2426 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode))
2427 {
2428 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
2429 operands[1]));
2430 DONE;
2431 }
2432})
2433
2434(define_insn "*zero_extendqihi2"
2435 [(set (match_operand:HI 0 "register_operand" "=d,d")
2436 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2437 "!TARGET_MIPS16"
2438 "@
2439 andi\t%0,%1,0x00ff
2440 lbu\t%0,%1"
2441 [(set_attr "type" "arith,load")
2442 (set_attr "mode" "HI")])
2443
2444(define_insn "*zero_extendqihi2_mips16"
2445 [(set (match_operand:HI 0 "register_operand" "=d")
2446 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2447 "TARGET_MIPS16"
2448 "lbu\t%0,%1"
2449 [(set_attr "type" "load")
2450 (set_attr "mode" "HI")])
2451
2452;;
2453;; ....................
2454;;
2455;; SIGN EXTENSION
2456;;
2457;; ....................
2458
2459;; Extension insns.
2460;; Those for integer source operand are ordered widest source type first.
2461
2462;; When TARGET_64BIT, all SImode integer registers should already be in
2463;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
2464;; therefore get rid of register->register instructions if we constrain
2465;; the source to be in the same register as the destination.
2466;;
2467;; The register alternative has type "arith" so that the pre-reload
2468;; scheduler will treat it as a move. This reflects what happens if
2469;; the register alternative needs a reload.
2470(define_insn_and_split "extendsidi2"
2471 [(set (match_operand:DI 0 "register_operand" "=d,d")
2472 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2473 "TARGET_64BIT"
2474 "@
2475 #
2476 lw\t%0,%1"
2477 "&& reload_completed && register_operand (operands[1], VOIDmode)"
2478 [(const_int 0)]
2479{
2480 emit_note (NOTE_INSN_DELETED);
2481 DONE;
2482}
2483 [(set_attr "type" "arith,load")
2484 (set_attr "mode" "DI")])
2485
2486(define_expand "extend<SHORT:mode><GPR:mode>2"
2487 [(set (match_operand:GPR 0 "register_operand")
2488 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
2489 "")
2490
2491(define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e"
2492 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2493 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))]
2494 "GENERATE_MIPS16E"
2495 "@
2496 se<SHORT:size>\t%0
2497 l<SHORT:size>\t%0,%1"
2498 [(set_attr "type" "arith,load")
2499 (set_attr "mode" "<GPR:MODE>")])
2500
2501(define_insn_and_split "*extend<SHORT:mode><GPR:mode>2"
2502 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2503 (sign_extend:GPR
2504 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2505 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E"
2506 "@
2507 #
2508 l<SHORT:size>\t%0,%1"
2509 "&& reload_completed && REG_P (operands[1])"
2510 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2)))
2511 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))]
2512{
2513 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]);
2514 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode)
2515 - GET_MODE_BITSIZE (<SHORT:MODE>mode));
2516}
2517 [(set_attr "type" "arith,load")
2518 (set_attr "mode" "<GPR:MODE>")
2519 (set_attr "length" "8,*")])
2520
2521(define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>"
2522 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2523 (sign_extend:GPR
2524 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
2525 "ISA_HAS_SEB_SEH"
2526 "@
2527 se<SHORT:size>\t%0,%1
2528 l<SHORT:size>\t%0,%1"
2529 [(set_attr "type" "arith,load")
2530 (set_attr "mode" "<GPR:MODE>")])
2531
2532;; This pattern generates the same code as extendqisi2; split it into
2533;; that form after reload.
2534(define_insn_and_split "extendqihi2"
2535 [(set (match_operand:HI 0 "register_operand" "=d,d")
2536 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2537 ""
2538 "#"
2539 "reload_completed"
2540 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
2541 { operands[0] = gen_lowpart (SImode, operands[0]); }
2542 [(set_attr "type" "arith,load")
2543 (set_attr "mode" "SI")
2544 (set_attr "length" "8,*")])
2545
2546(define_insn "extendsfdf2"
2547 [(set (match_operand:DF 0 "register_operand" "=f")
2548 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2549 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2550 "cvt.d.s\t%0,%1"
2551 [(set_attr "type" "fcvt")
2552 (set_attr "cnv_mode" "S2D")
2553 (set_attr "mode" "DF")])
2554
2555;;
2556;; ....................
2557;;
2558;; CONVERSIONS
2559;;
2560;; ....................
2561
2562(define_expand "fix_truncdfsi2"
2563 [(set (match_operand:SI 0 "register_operand")
2564 (fix:SI (match_operand:DF 1 "register_operand")))]
2565 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2566{
2567 if (!ISA_HAS_TRUNC_W)
2568 {
2569 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2570 DONE;
2571 }
2572})
2573
2574(define_insn "fix_truncdfsi2_insn"
2575 [(set (match_operand:SI 0 "register_operand" "=f")
2576 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2577 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2578 "trunc.w.d %0,%1"
2579 [(set_attr "type" "fcvt")
2580 (set_attr "mode" "DF")
2581 (set_attr "cnv_mode" "D2I")
2582 (set_attr "length" "4")])
2583
2584(define_insn "fix_truncdfsi2_macro"
2585 [(set (match_operand:SI 0 "register_operand" "=f")
2586 (fix:SI (match_operand:DF 1 "register_operand" "f")))
2587 (clobber (match_scratch:DF 2 "=d"))]
2588 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2589{
2590 if (set_nomacro)
2591 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2592 else
2593 return "trunc.w.d %0,%1,%2";
2594}
2595 [(set_attr "type" "fcvt")
2596 (set_attr "mode" "DF")
2597 (set_attr "cnv_mode" "D2I")
2598 (set_attr "length" "36")])
2599
2600(define_expand "fix_truncsfsi2"
2601 [(set (match_operand:SI 0 "register_operand")
2602 (fix:SI (match_operand:SF 1 "register_operand")))]
2603 "TARGET_HARD_FLOAT"
2604{
2605 if (!ISA_HAS_TRUNC_W)
2606 {
2607 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2608 DONE;
2609 }
2610})
2611
2612(define_insn "fix_truncsfsi2_insn"
2613 [(set (match_operand:SI 0 "register_operand" "=f")
2614 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2615 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2616 "trunc.w.s %0,%1"
2617 [(set_attr "type" "fcvt")
2618 (set_attr "mode" "SF")
2619 (set_attr "cnv_mode" "S2I")
2620 (set_attr "length" "4")])
2621
2622(define_insn "fix_truncsfsi2_macro"
2623 [(set (match_operand:SI 0 "register_operand" "=f")
2624 (fix:SI (match_operand:SF 1 "register_operand" "f")))
2625 (clobber (match_scratch:SF 2 "=d"))]
2626 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2627{
2628 if (set_nomacro)
2629 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2630 else
2631 return "trunc.w.s %0,%1,%2";
2632}
2633 [(set_attr "type" "fcvt")
2634 (set_attr "mode" "SF")
2635 (set_attr "cnv_mode" "S2I")
2636 (set_attr "length" "36")])
2637
2638
2639(define_insn "fix_truncdfdi2"
2640 [(set (match_operand:DI 0 "register_operand" "=f")
2641 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2642 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2643 "trunc.l.d %0,%1"
2644 [(set_attr "type" "fcvt")
2645 (set_attr "mode" "DF")
2646 (set_attr "cnv_mode" "D2I")
2647 (set_attr "length" "4")])
2648
2649
2650(define_insn "fix_truncsfdi2"
2651 [(set (match_operand:DI 0 "register_operand" "=f")
2652 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2653 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2654 "trunc.l.s %0,%1"
2655 [(set_attr "type" "fcvt")
2656 (set_attr "mode" "SF")
2657 (set_attr "cnv_mode" "S2I")
2658 (set_attr "length" "4")])
2659
2660
2661(define_insn "floatsidf2"
2662 [(set (match_operand:DF 0 "register_operand" "=f")
2663 (float:DF (match_operand:SI 1 "register_operand" "f")))]
2664 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2665 "cvt.d.w\t%0,%1"
2666 [(set_attr "type" "fcvt")
2667 (set_attr "mode" "DF")
2668 (set_attr "cnv_mode" "I2D")
2669 (set_attr "length" "4")])
2670
2671
2672(define_insn "floatdidf2"
2673 [(set (match_operand:DF 0 "register_operand" "=f")
2674 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2675 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2676 "cvt.d.l\t%0,%1"
2677 [(set_attr "type" "fcvt")
2678 (set_attr "mode" "DF")
2679 (set_attr "cnv_mode" "I2D")
2680 (set_attr "length" "4")])
2681
2682
2683(define_insn "floatsisf2"
2684 [(set (match_operand:SF 0 "register_operand" "=f")
2685 (float:SF (match_operand:SI 1 "register_operand" "f")))]
2686 "TARGET_HARD_FLOAT"
2687 "cvt.s.w\t%0,%1"
2688 [(set_attr "type" "fcvt")
2689 (set_attr "mode" "SF")
2690 (set_attr "cnv_mode" "I2S")
2691 (set_attr "length" "4")])
2692
2693
2694(define_insn "floatdisf2"
2695 [(set (match_operand:SF 0 "register_operand" "=f")
2696 (float:SF (match_operand:DI 1 "register_operand" "f")))]
2697 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2698 "cvt.s.l\t%0,%1"
2699 [(set_attr "type" "fcvt")
2700 (set_attr "mode" "SF")
2701 (set_attr "cnv_mode" "I2S")
2702 (set_attr "length" "4")])
2703
2704
2705(define_expand "fixuns_truncdfsi2"
2706 [(set (match_operand:SI 0 "register_operand")
2707 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2708 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2709{
2710 rtx reg1 = gen_reg_rtx (DFmode);
2711 rtx reg2 = gen_reg_rtx (DFmode);
2712 rtx reg3 = gen_reg_rtx (SImode);
2713 rtx label1 = gen_label_rtx ();
2714 rtx label2 = gen_label_rtx ();
2715 REAL_VALUE_TYPE offset;
2716
2717 real_2expN (&offset, 31);
2718
2719 if (reg1) /* Turn off complaints about unreached code. */
2720 {
2721 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2722 do_pending_stack_adjust ();
2723
2724 emit_insn (gen_cmpdf (operands[1], reg1));
2725 emit_jump_insn (gen_bge (label1));
2726
2727 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2728 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2729 gen_rtx_LABEL_REF (VOIDmode, label2)));
2730 emit_barrier ();
2731
2732 emit_label (label1);
2733 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2734 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2735 (BITMASK_HIGH, SImode)));
2736
2737 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2738 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2739
2740 emit_label (label2);
2741
2742 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2743 fields, and can't be used for REG_NOTES anyway). */
2744 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2745 DONE;
2746 }
2747})
2748
2749
2750(define_expand "fixuns_truncdfdi2"
2751 [(set (match_operand:DI 0 "register_operand")
2752 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2753 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2754{
2755 rtx reg1 = gen_reg_rtx (DFmode);
2756 rtx reg2 = gen_reg_rtx (DFmode);
2757 rtx reg3 = gen_reg_rtx (DImode);
2758 rtx label1 = gen_label_rtx ();
2759 rtx label2 = gen_label_rtx ();
2760 REAL_VALUE_TYPE offset;
2761
2762 real_2expN (&offset, 63);
2763
2764 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2765 do_pending_stack_adjust ();
2766
2767 emit_insn (gen_cmpdf (operands[1], reg1));
2768 emit_jump_insn (gen_bge (label1));
2769
2770 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2771 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2772 gen_rtx_LABEL_REF (VOIDmode, label2)));
2773 emit_barrier ();
2774
2775 emit_label (label1);
2776 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2777 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2778 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2779
2780 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2781 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2782
2783 emit_label (label2);
2784
2785 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2786 fields, and can't be used for REG_NOTES anyway). */
2787 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2788 DONE;
2789})
2790
2791
2792(define_expand "fixuns_truncsfsi2"
2793 [(set (match_operand:SI 0 "register_operand")
2794 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2795 "TARGET_HARD_FLOAT"
2796{
2797 rtx reg1 = gen_reg_rtx (SFmode);
2798 rtx reg2 = gen_reg_rtx (SFmode);
2799 rtx reg3 = gen_reg_rtx (SImode);
2800 rtx label1 = gen_label_rtx ();
2801 rtx label2 = gen_label_rtx ();
2802 REAL_VALUE_TYPE offset;
2803
2804 real_2expN (&offset, 31);
2805
2806 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2807 do_pending_stack_adjust ();
2808
2809 emit_insn (gen_cmpsf (operands[1], reg1));
2810 emit_jump_insn (gen_bge (label1));
2811
2812 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2813 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2814 gen_rtx_LABEL_REF (VOIDmode, label2)));
2815 emit_barrier ();
2816
2817 emit_label (label1);
2818 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2819 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2820 (BITMASK_HIGH, SImode)));
2821
2822 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2823 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2824
2825 emit_label (label2);
2826
2827 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2828 fields, and can't be used for REG_NOTES anyway). */
2829 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2830 DONE;
2831})
2832
2833
2834(define_expand "fixuns_truncsfdi2"
2835 [(set (match_operand:DI 0 "register_operand")
2836 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2837 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2838{
2839 rtx reg1 = gen_reg_rtx (SFmode);
2840 rtx reg2 = gen_reg_rtx (SFmode);
2841 rtx reg3 = gen_reg_rtx (DImode);
2842 rtx label1 = gen_label_rtx ();
2843 rtx label2 = gen_label_rtx ();
2844 REAL_VALUE_TYPE offset;
2845
2846 real_2expN (&offset, 63);
2847
2848 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2849 do_pending_stack_adjust ();
2850
2851 emit_insn (gen_cmpsf (operands[1], reg1));
2852 emit_jump_insn (gen_bge (label1));
2853
2854 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2855 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2856 gen_rtx_LABEL_REF (VOIDmode, label2)));
2857 emit_barrier ();
2858
2859 emit_label (label1);
2860 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2861 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2862 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2863
2864 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2865 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2866
2867 emit_label (label2);
2868
2869 /* Allow REG_NOTES to be set on last insn (labels don't have enough
2870 fields, and can't be used for REG_NOTES anyway). */
2871 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2872 DONE;
2873})
2874
2875;;
2876;; ....................
2877;;
2878;; DATA MOVEMENT
2879;;
2880;; ....................
2881
2882;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2883
2884(define_expand "extv"
2885 [(set (match_operand 0 "register_operand")
2886 (sign_extract (match_operand:QI 1 "memory_operand")
2887 (match_operand 2 "immediate_operand")
2888 (match_operand 3 "immediate_operand")))]
2889 "!TARGET_MIPS16"
2890{
2891 if (mips_expand_unaligned_load (operands[0], operands[1],
2892 INTVAL (operands[2]),
2893 INTVAL (operands[3])))
2894 DONE;
2895 else
2896 FAIL;
2897})
2898
2899(define_expand "extzv"
2900 [(set (match_operand 0 "register_operand")
2901 (zero_extract (match_operand 1 "nonimmediate_operand")
2902 (match_operand 2 "immediate_operand")
2903 (match_operand 3 "immediate_operand")))]
2904 "!TARGET_MIPS16"
2905{
2906 if (mips_expand_unaligned_load (operands[0], operands[1],
2907 INTVAL (operands[2]),
2908 INTVAL (operands[3])))
2909 DONE;
2910 else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
2911 {
2912 if (GET_MODE (operands[0]) == DImode)
2913 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
2914 operands[3]));
2915 else
2916 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
2917 operands[3]));
2918 DONE;
2919 }
2920 else
2921 FAIL;
2922})
2923
2924(define_insn "extzv<mode>"
2925 [(set (match_operand:GPR 0 "register_operand" "=d")
2926 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
2927 (match_operand:SI 2 "immediate_operand" "I")
2928 (match_operand:SI 3 "immediate_operand" "I")))]
2929 "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
2930 "<d>ext\t%0,%1,%3,%2"
2931 [(set_attr "type" "arith")
2932 (set_attr "mode" "<MODE>")])
2933
2934
2935(define_expand "insv"
2936 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2937 (match_operand 1 "immediate_operand")
2938 (match_operand 2 "immediate_operand"))
2939 (match_operand 3 "reg_or_0_operand"))]
2940 "!TARGET_MIPS16"
2941{
2942 if (mips_expand_unaligned_store (operands[0], operands[3],
2943 INTVAL (operands[1]),
2944 INTVAL (operands[2])))
2945 DONE;
2946 else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
2947 {
2948 if (GET_MODE (operands[0]) == DImode)
2949 emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
2950 operands[3]));
2951 else
2952 emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
2953 operands[3]));
2954 DONE;
2955 }
2956 else
2957 FAIL;
2958})
2959
2960(define_insn "insv<mode>"
2961 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
2962 (match_operand:SI 1 "immediate_operand" "I")
2963 (match_operand:SI 2 "immediate_operand" "I"))
2964 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
2965 "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
2966 "<d>ins\t%0,%z3,%2,%1"
2967 [(set_attr "type" "arith")
2968 (set_attr "mode" "<MODE>")])
2969
2970;; Unaligned word moves generated by the bit field patterns.
2971;;
2972;; As far as the rtl is concerned, both the left-part and right-part
2973;; instructions can access the whole field. However, the real operand
2974;; refers to just the first or the last byte (depending on endianness).
2975;; We therefore use two memory operands to each instruction, one to
2976;; describe the rtl effect and one to use in the assembly output.
2977;;
2978;; Operands 0 and 1 are the rtl-level target and source respectively.
2979;; This allows us to use the standard length calculations for the "load"
2980;; and "store" type attributes.
2981
2982(define_insn "mov_<load>l"
2983 [(set (match_operand:GPR 0 "register_operand" "=d")
2984 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2985 (match_operand:QI 2 "memory_operand" "m")]
2986 UNSPEC_LOAD_LEFT))]
2987 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
2988 "<load>l\t%0,%2"
2989 [(set_attr "type" "load")
2990 (set_attr "mode" "<MODE>")])
2991
2992(define_insn "mov_<load>r"
2993 [(set (match_operand:GPR 0 "register_operand" "=d")
2994 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
2995 (match_operand:QI 2 "memory_operand" "m")
2996 (match_operand:GPR 3 "register_operand" "0")]
2997 UNSPEC_LOAD_RIGHT))]
2998 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])"
2999 "<load>r\t%0,%2"
3000 [(set_attr "type" "load")
3001 (set_attr "mode" "<MODE>")])
3002
3003(define_insn "mov_<store>l"
3004 [(set (match_operand:BLK 0 "memory_operand" "=m")
3005 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3006 (match_operand:QI 2 "memory_operand" "m")]
3007 UNSPEC_STORE_LEFT))]
3008 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3009 "<store>l\t%z1,%2"
3010 [(set_attr "type" "store")
3011 (set_attr "mode" "<MODE>")])
3012
3013(define_insn "mov_<store>r"
3014 [(set (match_operand:BLK 0 "memory_operand" "+m")
3015 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3016 (match_operand:QI 2 "memory_operand" "m")
3017 (match_dup 0)]
3018 UNSPEC_STORE_RIGHT))]
3019 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])"
3020 "<store>r\t%z1,%2"
3021 [(set_attr "type" "store")
3022 (set_attr "mode" "<MODE>")])
3023
3024;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3025;; The required value is:
3026;;
3027;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3028;;
3029;; which translates to:
3030;;
3031;; lui op0,%highest(op1)
3032;; daddiu op0,op0,%higher(op1)
3033;; dsll op0,op0,16
3034;; daddiu op0,op0,%hi(op1)
3035;; dsll op0,op0,16
3036;;
3037;; The split is deferred until after flow2 to allow the peephole2 below
3038;; to take effect.
3039(define_insn_and_split "*lea_high64"
3040 [(set (match_operand:DI 0 "register_operand" "=d")
3041 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3042 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3043 "#"
3044 "&& flow2_completed"
3045 [(set (match_dup 0) (high:DI (match_dup 2)))
3046 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3047 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3048 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3049 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3050{
3051 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3052 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3053}
3054 [(set_attr "length" "20")])
3055
3056;; Use a scratch register to reduce the latency of the above pattern
3057;; on superscalar machines. The optimized sequence is:
3058;;
3059;; lui op1,%highest(op2)
3060;; lui op0,%hi(op2)
3061;; daddiu op1,op1,%higher(op2)
3062;; dsll32 op1,op1,0
3063;; daddu op1,op1,op0
3064(define_peephole2
3065 [(set (match_operand:DI 1 "register_operand")
3066 (high:DI (match_operand:DI 2 "general_symbolic_operand")))
3067 (match_scratch:DI 0 "d")]
3068 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3069 [(set (match_dup 1) (high:DI (match_dup 3)))
3070 (set (match_dup 0) (high:DI (match_dup 4)))
3071 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3072 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3073 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3074{
3075 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3076 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3077})
3078
3079;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3080;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3081;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3082;; used once. We can then use the sequence:
3083;;
3084;; lui op0,%highest(op1)
3085;; lui op2,%hi(op1)
3086;; daddiu op0,op0,%higher(op1)
3087;; daddiu op2,op2,%lo(op1)
3088;; dsll32 op0,op0,0
3089;; daddu op0,op0,op2
3090;;
3091;; which takes 4 cycles on most superscalar targets.
3092(define_insn_and_split "*lea64"
3093 [(set (match_operand:DI 0 "register_operand" "=d")
3094 (match_operand:DI 1 "general_symbolic_operand" ""))
3095 (clobber (match_scratch:DI 2 "=&d"))]
3096 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3097 "#"
3098 "&& reload_completed"
3099 [(set (match_dup 0) (high:DI (match_dup 3)))
3100 (set (match_dup 2) (high:DI (match_dup 4)))
3101 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3102 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3103 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3104 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3105{
3106 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3107 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3108}
3109 [(set_attr "length" "24")])
3110
3111;; Insns to fetch a global symbol from a big GOT.
3112
3113(define_insn_and_split "*xgot_hi<mode>"
3114 [(set (match_operand:P 0 "register_operand" "=d")
3115 (high:P (match_operand:P 1 "global_got_operand" "")))]
3116 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3117 "#"
3118 "&& reload_completed"
3119 [(set (match_dup 0) (high:P (match_dup 2)))
3120 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3121{
3122 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3123 operands[3] = pic_offset_table_rtx;
3124}
3125 [(set_attr "got" "xgot_high")
3126 (set_attr "mode" "<MODE>")])
3127
3128(define_insn_and_split "*xgot_lo<mode>"
3129 [(set (match_operand:P 0 "register_operand" "=d")
3130 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3131 (match_operand:P 2 "global_got_operand" "")))]
3132 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3133 "#"
3134 "&& reload_completed"
3135 [(set (match_dup 0)
3136 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3137 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3138 [(set_attr "got" "load")
3139 (set_attr "mode" "<MODE>")])
3140
3141;; Insns to fetch a global symbol from a normal GOT.
3142
3143(define_insn_and_split "*got_disp<mode>"
3144 [(set (match_operand:P 0 "register_operand" "=d")
3145 (match_operand:P 1 "global_got_operand" ""))]
3146 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3147 "#"
3148 "&& reload_completed"
3149 [(set (match_dup 0)
3150 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3151{
3152 operands[2] = pic_offset_table_rtx;
3153 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3154}
3155 [(set_attr "got" "load")
3156 (set_attr "mode" "<MODE>")])
3157
3158;; Insns for loading the high part of a local symbol.
3159
3160(define_insn_and_split "*got_page<mode>"
3161 [(set (match_operand:P 0 "register_operand" "=d")
3162 (high:P (match_operand:P 1 "local_got_operand" "")))]
3163 "TARGET_EXPLICIT_RELOCS"
3164 "#"
3165 "&& reload_completed"
3166 [(set (match_dup 0)
3167 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3168{
3169 operands[2] = pic_offset_table_rtx;
3170 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3171}
3172 [(set_attr "got" "load")
3173 (set_attr "mode" "<MODE>")])
3174
3175;; Lower-level instructions for loading an address from the GOT.
3176;; We could use MEMs, but an unspec gives more optimization
3177;; opportunities.
3178
3179(define_insn "load_got<mode>"
3180 [(set (match_operand:P 0 "register_operand" "=d")
3181 (unspec:P [(match_operand:P 1 "register_operand" "d")
3182 (match_operand:P 2 "immediate_operand" "")]
3183 UNSPEC_LOAD_GOT))]
3184 ""
3185 "<load>\t%0,%R2(%1)"
3186 [(set_attr "type" "load")
3187 (set_attr "mode" "<MODE>")
3188 (set_attr "length" "4")])
3189
3190;; Instructions for adding the low 16 bits of an address to a register.
3191;; Operand 2 is the address: print_operand works out which relocation
3192;; should be applied.
3193
3194(define_insn "*low<mode>"
3195 [(set (match_operand:P 0 "register_operand" "=d")
3196 (lo_sum:P (match_operand:P 1 "register_operand" "d")
3197 (match_operand:P 2 "immediate_operand" "")))]
3198 "!TARGET_MIPS16"
3199 "<d>addiu\t%0,%1,%R2"
3200 [(set_attr "type" "arith")
3201 (set_attr "mode" "<MODE>")])
3202
3203(define_insn "*low<mode>_mips16"
3204 [(set (match_operand:P 0 "register_operand" "=d")
3205 (lo_sum:P (match_operand:P 1 "register_operand" "0")
3206 (match_operand:P 2 "immediate_operand" "")))]
3207 "TARGET_MIPS16"
3208 "<d>addiu\t%0,%R2"
3209 [(set_attr "type" "arith")
3210 (set_attr "mode" "<MODE>")
3211 (set_attr "length" "8")])
3212
3213;; Allow combine to split complex const_int load sequences, using operand 2
3214;; to store the intermediate results. See move_operand for details.
3215(define_split
3216 [(set (match_operand:GPR 0 "register_operand")
3217 (match_operand:GPR 1 "splittable_const_int_operand"))
3218 (clobber (match_operand:GPR 2 "register_operand"))]
3219 ""
3220 [(const_int 0)]
3221{
3222 mips_move_integer (operands[0], operands[2], INTVAL (operands[1]));
3223 DONE;
3224})
3225
3226;; Likewise, for symbolic operands.
3227(define_split
3228 [(set (match_operand:P 0 "register_operand")
3229 (match_operand:P 1 "splittable_symbolic_operand"))
3230 (clobber (match_operand:P 2 "register_operand"))]
3231 ""
3232 [(set (match_dup 0) (match_dup 1))]
3233 { operands[1] = mips_split_symbol (operands[2], operands[1]); })
3234
3235;; 64-bit integer moves
3236
3237;; Unlike most other insns, the move insns can't be split with
3238;; different predicates, because register spilling and other parts of
3239;; the compiler, have memoized the insn number already.
3240
3241(define_expand "movdi"
3242 [(set (match_operand:DI 0 "")
3243 (match_operand:DI 1 ""))]
3244 ""
3245{
3246 if (mips_legitimize_move (DImode, operands[0], operands[1]))
3247 DONE;
3248})
3249
3250;; For mips16, we need a special case to handle storing $31 into
3251;; memory, since we don't have a constraint to match $31. This
3252;; instruction can be generated by save_restore_insns.
3253
3254(define_insn "*mov<mode>_ra"
3255 [(set (match_operand:GPR 0 "stack_operand" "=m")
3256 (reg:GPR 31))]
3257 "TARGET_MIPS16"
3258 "<store>\t$31,%0"
3259 [(set_attr "type" "store")
3260 (set_attr "mode" "<MODE>")])
3261
3262(define_insn "*movdi_32bit"
3263 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
3264 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
3265 "!TARGET_64BIT && !TARGET_MIPS16
3266 && (register_operand (operands[0], DImode)
3267 || reg_or_0_operand (operands[1], DImode))"
3268 { return mips_output_move (operands[0], operands[1]); }
3269 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3270 (set_attr "mode" "DI")
3271 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
3272
3273(define_insn "*movdi_32bit_mips16"
3274 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3275 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3276 "!TARGET_64BIT && TARGET_MIPS16
3277 && (register_operand (operands[0], DImode)
3278 || register_operand (operands[1], DImode))"
3279 { return mips_output_move (operands[0], operands[1]); }
3280 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
3281 (set_attr "mode" "DI")
3282 (set_attr "length" "8,8,8,8,12,*,*,8")])
3283
3284(define_insn "*movdi_64bit"
3285 [(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")
3286 (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"))]
3287 "TARGET_64BIT && !TARGET_MIPS16
3288 && (register_operand (operands[0], DImode)
3289 || reg_or_0_operand (operands[1], DImode))"
3290 { return mips_output_move (operands[0], operands[1]); }
3291 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3292 (set_attr "mode" "DI")
3293 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3294
3295(define_insn "*movdi_64bit_mips16"
3296 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3297 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3298 "TARGET_64BIT && TARGET_MIPS16
3299 && (register_operand (operands[0], DImode)
3300 || register_operand (operands[1], DImode))"
3301 { return mips_output_move (operands[0], operands[1]); }
3302 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3303 (set_attr "mode" "DI")
3304 (set_attr_alternative "length"
3305 [(const_int 4)
3306 (const_int 4)
3307 (const_int 4)
3308 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3309 (const_int 4)
3310 (const_int 8))
3311 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3312 (const_int 8)
3313 (const_int 12))
3314 (const_string "*")
3315 (const_string "*")
3316 (const_string "*")])])
3317
3318
3319;; On the mips16, we can split ld $r,N($r) into an add and a load,
3320;; when the original load is a 4 byte instruction but the add and the
3321;; load are 2 2 byte instructions.
3322
3323(define_split
3324 [(set (match_operand:DI 0 "register_operand")
3325 (mem:DI (plus:DI (match_dup 0)
3326 (match_operand:DI 1 "const_int_operand"))))]
3327 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3328 && !TARGET_DEBUG_D_MODE
3329 && REG_P (operands[0])
3330 && M16_REG_P (REGNO (operands[0]))
3331 && GET_CODE (operands[1]) == CONST_INT
3332 && ((INTVAL (operands[1]) < 0
3333 && INTVAL (operands[1]) >= -0x10)
3334 || (INTVAL (operands[1]) >= 32 * 8
3335 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3336 || (INTVAL (operands[1]) >= 0
3337 && INTVAL (operands[1]) < 32 * 8
3338 && (INTVAL (operands[1]) & 7) != 0))"
3339 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3340 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3341{
3342 HOST_WIDE_INT val = INTVAL (operands[1]);
3343
3344 if (val < 0)
3345 operands[2] = const0_rtx;
3346 else if (val >= 32 * 8)
3347 {
3348 int off = val & 7;
3349
3350 operands[1] = GEN_INT (0x8 + off);
3351 operands[2] = GEN_INT (val - off - 0x8);
3352 }
3353 else
3354 {
3355 int off = val & 7;
3356
3357 operands[1] = GEN_INT (off);
3358 operands[2] = GEN_INT (val - off);
3359 }
3360})
3361
3362;; 32-bit Integer moves
3363
3364;; Unlike most other insns, the move insns can't be split with
3365;; different predicates, because register spilling and other parts of
3366;; the compiler, have memoized the insn number already.
3367
3368(define_expand "movsi"
3369 [(set (match_operand:SI 0 "")
3370 (match_operand:SI 1 ""))]
3371 ""
3372{
3373 if (mips_legitimize_move (SImode, operands[0], operands[1]))
3374 DONE;
3375})
3376
3377;; The difference between these two is whether or not ints are allowed
3378;; in FP registers (off by default, use -mdebugh to enable).
3379
3380(define_insn "*movsi_internal"
3381 [(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")
3382 (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"))]
3383 "!TARGET_MIPS16
3384 && (register_operand (operands[0], SImode)
3385 || reg_or_0_operand (operands[1], SImode))"
3386 { return mips_output_move (operands[0], operands[1]); }
3387 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
3388 (set_attr "mode" "SI")
3389 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
3390
3391(define_insn "*movsi_mips16"
3392 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3393 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3394 "TARGET_MIPS16
3395 && (register_operand (operands[0], SImode)
3396 || register_operand (operands[1], SImode))"
3397 { return mips_output_move (operands[0], operands[1]); }
3398 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
3399 (set_attr "mode" "SI")
3400 (set_attr_alternative "length"
3401 [(const_int 4)
3402 (const_int 4)
3403 (const_int 4)
3404 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3405 (const_int 4)
3406 (const_int 8))
3407 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3408 (const_int 8)
3409 (const_int 12))
3410 (const_string "*")
3411 (const_string "*")
3412 (const_string "*")])])
3413
3414;; On the mips16, we can split lw $r,N($r) into an add and a load,
3415;; when the original load is a 4 byte instruction but the add and the
3416;; load are 2 2 byte instructions.
3417
3418(define_split
3419 [(set (match_operand:SI 0 "register_operand")
3420 (mem:SI (plus:SI (match_dup 0)
3421 (match_operand:SI 1 "const_int_operand"))))]
3422 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3423 && REG_P (operands[0])
3424 && M16_REG_P (REGNO (operands[0]))
3425 && GET_CODE (operands[1]) == CONST_INT
3426 && ((INTVAL (operands[1]) < 0
3427 && INTVAL (operands[1]) >= -0x80)
3428 || (INTVAL (operands[1]) >= 32 * 4
3429 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
3430 || (INTVAL (operands[1]) >= 0
3431 && INTVAL (operands[1]) < 32 * 4
3432 && (INTVAL (operands[1]) & 3) != 0))"
3433 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3434 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
3435{
3436 HOST_WIDE_INT val = INTVAL (operands[1]);
3437
3438 if (val < 0)
3439 operands[2] = const0_rtx;
3440 else if (val >= 32 * 4)
3441 {
3442 int off = val & 3;
3443
3444 operands[1] = GEN_INT (0x7c + off);
3445 operands[2] = GEN_INT (val - off - 0x7c);
3446 }
3447 else
3448 {
3449 int off = val & 3;
3450
3451 operands[1] = GEN_INT (off);
3452 operands[2] = GEN_INT (val - off);
3453 }
3454})
3455
3456;; On the mips16, we can split a load of certain constants into a load
3457;; and an add. This turns a 4 byte instruction into 2 2 byte
3458;; instructions.
3459
3460(define_split
3461 [(set (match_operand:SI 0 "register_operand")
3462 (match_operand:SI 1 "const_int_operand"))]
3463 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3464 && REG_P (operands[0])
3465 && M16_REG_P (REGNO (operands[0]))
3466 && GET_CODE (operands[1]) == CONST_INT
3467 && INTVAL (operands[1]) >= 0x100
3468 && INTVAL (operands[1]) <= 0xff + 0x7f"
3469 [(set (match_dup 0) (match_dup 1))
3470 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
3471{
3472 int val = INTVAL (operands[1]);
3473
3474 operands[1] = GEN_INT (0xff);
3475 operands[2] = GEN_INT (val - 0xff);
3476})
3477
3478;; This insn handles moving CCmode values. It's really just a
3479;; slightly simplified copy of movsi_internal2, with additional cases
3480;; to move a condition register to a general register and to move
3481;; between the general registers and the floating point registers.
3482
3483(define_insn "movcc"
3484 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
3485 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
3486 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3487 { return mips_output_move (operands[0], operands[1]); }
3488 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
3489 (set_attr "mode" "SI")
3490 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
3491
3492;; Reload condition code registers. reload_incc and reload_outcc
3493;; both handle moves from arbitrary operands into condition code
3494;; registers. reload_incc handles the more common case in which
3495;; a source operand is constrained to be in a condition-code
3496;; register, but has not been allocated to one.
3497;;
3498;; Sometimes, such as in movcc, we have a CCmode destination whose
3499;; constraints do not include 'z'. reload_outcc handles the case
3500;; when such an operand is allocated to a condition-code register.
3501;;
3502;; Note that reloads from a condition code register to some
3503;; other location can be done using ordinary moves. Moving
3504;; into a GPR takes a single movcc, moving elsewhere takes
3505;; two. We can leave these cases to the generic reload code.
3506(define_expand "reload_incc"
3507 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3508 (match_operand:CC 1 "general_operand" ""))
3509 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3510 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3511{
3512 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3513 DONE;
3514})
3515
3516(define_expand "reload_outcc"
3517 [(set (match_operand:CC 0 "fcc_reload_operand" "=z")
3518 (match_operand:CC 1 "register_operand" ""))
3519 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3520 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
3521{
3522 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
3523 DONE;
3524})
3525
3526;; MIPS4 supports loading and storing a floating point register from
3527;; the sum of two general registers. We use two versions for each of
3528;; these four instructions: one where the two general registers are
3529;; SImode, and one where they are DImode. This is because general
3530;; registers will be in SImode when they hold 32 bit values, but,
3531;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3532;; instructions will still work correctly.
3533
3534;; ??? Perhaps it would be better to support these instructions by
3535;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3536;; these instructions can only be used to load and store floating
3537;; point registers, that would probably cause trouble in reload.
3538
3539(define_insn "*<ANYF:loadx>_<P:mode>"
3540 [(set (match_operand:ANYF 0 "register_operand" "=f")
3541 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3542 (match_operand:P 2 "register_operand" "d"))))]
3543 "ISA_HAS_FP4"
3544 "<ANYF:loadx>\t%0,%1(%2)"
3545 [(set_attr "type" "fpidxload")
3546 (set_attr "mode" "<ANYF:UNITMODE>")])
3547
3548(define_insn "*<ANYF:storex>_<P:mode>"
3549 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d")
3550 (match_operand:P 2 "register_operand" "d")))
3551 (match_operand:ANYF 0 "register_operand" "f"))]
3552 "ISA_HAS_FP4"
3553 "<ANYF:storex>\t%0,%1(%2)"
3554 [(set_attr "type" "fpidxstore")
3555 (set_attr "mode" "<ANYF:UNITMODE>")])
3556
3557;; 16-bit Integer moves
3558
3559;; Unlike most other insns, the move insns can't be split with
3560;; different predicates, because register spilling and other parts of
3561;; the compiler, have memoized the insn number already.
3562;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3563
3564(define_expand "movhi"
3565 [(set (match_operand:HI 0 "")
3566 (match_operand:HI 1 ""))]
3567 ""
3568{
3569 if (mips_legitimize_move (HImode, operands[0], operands[1]))
3570 DONE;
3571})
3572
3573(define_insn "*movhi_internal"
3574 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3575 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3576 "!TARGET_MIPS16
3577 && (register_operand (operands[0], HImode)
3578 || reg_or_0_operand (operands[1], HImode))"
3579 "@
3580 move\t%0,%1
3581 li\t%0,%1
3582 lhu\t%0,%1
3583 sh\t%z1,%0
3584 mfc1\t%0,%1
3585 mtc1\t%1,%0
3586 mov.s\t%0,%1
3587 mt%0\t%1"
3588 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3589 (set_attr "mode" "HI")
3590 (set_attr "length" "4,4,*,*,4,4,4,4")])
3591
3592(define_insn "*movhi_mips16"
3593 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3594 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
3595 "TARGET_MIPS16
3596 && (register_operand (operands[0], HImode)
3597 || register_operand (operands[1], HImode))"
3598 "@
3599 move\t%0,%1
3600 move\t%0,%1
3601 move\t%0,%1
3602 li\t%0,%1
3603 #
3604 lhu\t%0,%1
3605 sh\t%1,%0"
3606 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3607 (set_attr "mode" "HI")
3608 (set_attr_alternative "length"
3609 [(const_int 4)
3610 (const_int 4)
3611 (const_int 4)
3612 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3613 (const_int 4)
3614 (const_int 8))
3615 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3616 (const_int 8)
3617 (const_int 12))
3618 (const_string "*")
3619 (const_string "*")])])
3620
3621
3622;; On the mips16, we can split lh $r,N($r) into an add and a load,
3623;; when the original load is a 4 byte instruction but the add and the
3624;; load are 2 2 byte instructions.
3625
3626(define_split
3627 [(set (match_operand:HI 0 "register_operand")
3628 (mem:HI (plus:SI (match_dup 0)
3629 (match_operand:SI 1 "const_int_operand"))))]
3630 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3631 && REG_P (operands[0])
3632 && M16_REG_P (REGNO (operands[0]))
3633 && GET_CODE (operands[1]) == CONST_INT
3634 && ((INTVAL (operands[1]) < 0
3635 && INTVAL (operands[1]) >= -0x80)
3636 || (INTVAL (operands[1]) >= 32 * 2
3637 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
3638 || (INTVAL (operands[1]) >= 0
3639 && INTVAL (operands[1]) < 32 * 2
3640 && (INTVAL (operands[1]) & 1) != 0))"
3641 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3642 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
3643{
3644 HOST_WIDE_INT val = INTVAL (operands[1]);
3645
3646 if (val < 0)
3647 operands[2] = const0_rtx;
3648 else if (val >= 32 * 2)
3649 {
3650 int off = val & 1;
3651
3652 operands[1] = GEN_INT (0x7e + off);
3653 operands[2] = GEN_INT (val - off - 0x7e);
3654 }
3655 else
3656 {
3657 int off = val & 1;
3658
3659 operands[1] = GEN_INT (off);
3660 operands[2] = GEN_INT (val - off);
3661 }
3662})
3663
3664;; 8-bit Integer moves
3665
3666;; Unlike most other insns, the move insns can't be split with
3667;; different predicates, because register spilling and other parts of
3668;; the compiler, have memoized the insn number already.
3669;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
3670
3671(define_expand "movqi"
3672 [(set (match_operand:QI 0 "")
3673 (match_operand:QI 1 ""))]
3674 ""
3675{
3676 if (mips_legitimize_move (QImode, operands[0], operands[1]))
3677 DONE;
3678})
3679
3680(define_insn "*movqi_internal"
3681 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
3682 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
3683 "!TARGET_MIPS16
3684 && (register_operand (operands[0], QImode)
3685 || reg_or_0_operand (operands[1], QImode))"
3686 "@
3687 move\t%0,%1
3688 li\t%0,%1
3689 lbu\t%0,%1
3690 sb\t%z1,%0
3691 mfc1\t%0,%1
3692 mtc1\t%1,%0
3693 mov.s\t%0,%1
3694 mt%0\t%1"
3695 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
3696 (set_attr "mode" "QI")
3697 (set_attr "length" "4,4,*,*,4,4,4,4")])
3698
3699(define_insn "*movqi_mips16"
3700 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
3701 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
3702 "TARGET_MIPS16
3703 && (register_operand (operands[0], QImode)
3704 || register_operand (operands[1], QImode))"
3705 "@
3706 move\t%0,%1
3707 move\t%0,%1
3708 move\t%0,%1
3709 li\t%0,%1
3710 #
3711 lbu\t%0,%1
3712 sb\t%1,%0"
3713 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
3714 (set_attr "mode" "QI")
3715 (set_attr "length" "4,4,4,4,8,*,*")])
3716
3717;; On the mips16, we can split lb $r,N($r) into an add and a load,
3718;; when the original load is a 4 byte instruction but the add and the
3719;; load are 2 2 byte instructions.
3720
3721(define_split
3722 [(set (match_operand:QI 0 "register_operand")
3723 (mem:QI (plus:SI (match_dup 0)
3724 (match_operand:SI 1 "const_int_operand"))))]
3725 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
3726 && REG_P (operands[0])
3727 && M16_REG_P (REGNO (operands[0]))
3728 && GET_CODE (operands[1]) == CONST_INT
3729 && ((INTVAL (operands[1]) < 0
3730 && INTVAL (operands[1]) >= -0x80)
3731 || (INTVAL (operands[1]) >= 32
3732 && INTVAL (operands[1]) <= 31 + 0x7f))"
3733 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
3734 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
3735{
3736 HOST_WIDE_INT val = INTVAL (operands[1]);
3737
3738 if (val < 0)
3739 operands[2] = const0_rtx;
3740 else
3741 {
3742 operands[1] = GEN_INT (0x7f);
3743 operands[2] = GEN_INT (val - 0x7f);
3744 }
3745})
3746
3747;; 32-bit floating point moves
3748
3749(define_expand "movsf"
3750 [(set (match_operand:SF 0 "")
3751 (match_operand:SF 1 ""))]
3752 ""
3753{
3754 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
3755 DONE;
3756})
3757
3758(define_insn "*movsf_hardfloat"
3759 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3760 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))]
3761 "TARGET_HARD_FLOAT
3762 && (register_operand (operands[0], SFmode)
3763 || reg_or_0_operand (operands[1], SFmode))"
3764 { return mips_output_move (operands[0], operands[1]); }
3765 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3766 (set_attr "mode" "SF")
3767 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3768
3769(define_insn "*movsf_softfloat"
3770 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
3771 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
3772 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
3773 && (register_operand (operands[0], SFmode)
3774 || reg_or_0_operand (operands[1], SFmode))"
3775 { return mips_output_move (operands[0], operands[1]); }
3776 [(set_attr "type" "arith,load,store")
3777 (set_attr "mode" "SF")
3778 (set_attr "length" "4,*,*")])
3779
3780(define_insn "*movsf_mips16"
3781 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
3782 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
3783 "TARGET_MIPS16
3784 && (register_operand (operands[0], SFmode)
3785 || register_operand (operands[1], SFmode))"
3786 { return mips_output_move (operands[0], operands[1]); }
3787 [(set_attr "type" "arith,arith,arith,load,store")
3788 (set_attr "mode" "SF")
3789 (set_attr "length" "4,4,4,*,*")])
3790
3791
3792;; 64-bit floating point moves
3793
3794(define_expand "movdf"
3795 [(set (match_operand:DF 0 "")
3796 (match_operand:DF 1 ""))]
3797 ""
3798{
3799 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
3800 DONE;
3801})
3802
3803(define_insn "*movdf_hardfloat_64bit"
3804 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3805 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3806 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
3807 && (register_operand (operands[0], DFmode)
3808 || reg_or_0_operand (operands[1], DFmode))"
3809 { return mips_output_move (operands[0], operands[1]); }
3810 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3811 (set_attr "mode" "DF")
3812 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3813
3814(define_insn "*movdf_hardfloat_32bit"
3815 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3816 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))]
3817 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
3818 && (register_operand (operands[0], DFmode)
3819 || reg_or_0_operand (operands[1], DFmode))"
3820 { return mips_output_move (operands[0], operands[1]); }
3821 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3822 (set_attr "mode" "DF")
3823 (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
3824
3825(define_insn "*movdf_softfloat"
3826 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
3827 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
3828 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
3829 && (register_operand (operands[0], DFmode)
3830 || reg_or_0_operand (operands[1], DFmode))"
3831 { return mips_output_move (operands[0], operands[1]); }
3832 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
3833 (set_attr "mode" "DF")
3834 (set_attr "length" "8,*,*,4,4,4")])
3835
3836(define_insn "*movdf_mips16"
3837 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
3838 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
3839 "TARGET_MIPS16
3840 && (register_operand (operands[0], DFmode)
3841 || register_operand (operands[1], DFmode))"
3842 { return mips_output_move (operands[0], operands[1]); }
3843 [(set_attr "type" "arith,arith,arith,load,store")
3844 (set_attr "mode" "DF")
3845 (set_attr "length" "8,8,8,*,*")])
3846
3847(define_split
3848 [(set (match_operand:DI 0 "nonimmediate_operand")
3849 (match_operand:DI 1 "move_operand"))]
3850 "reload_completed && !TARGET_64BIT
3851 && mips_split_64bit_move_p (operands[0], operands[1])"
3852 [(const_int 0)]
3853{
3854 mips_split_64bit_move (operands[0], operands[1]);
3855 DONE;
3856})
3857
3858(define_split
3859 [(set (match_operand:DF 0 "nonimmediate_operand")
3860 (match_operand:DF 1 "move_operand"))]
3861 "reload_completed && !TARGET_64BIT
3862 && mips_split_64bit_move_p (operands[0], operands[1])"
3863 [(const_int 0)]
3864{
3865 mips_split_64bit_move (operands[0], operands[1]);
3866 DONE;
3867})
3868
3869;; When generating mips16 code, split moves of negative constants into
3870;; a positive "li" followed by a negation.
3871(define_split
3872 [(set (match_operand 0 "register_operand")
3873 (match_operand 1 "const_int_operand"))]
3874 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
3875 [(set (match_dup 2)
3876 (match_dup 3))
3877 (set (match_dup 2)
3878 (neg:SI (match_dup 2)))]
3879{
3880 operands[2] = gen_lowpart (SImode, operands[0]);
3881 operands[3] = GEN_INT (-INTVAL (operands[1]));
3882})
3883
3884;; 64-bit paired-single floating point moves
3885
3886(define_expand "movv2sf"
3887 [(set (match_operand:V2SF 0)
3888 (match_operand:V2SF 1))]
3889 "TARGET_PAIRED_SINGLE_FLOAT"
3890{
3891 if (mips_legitimize_move (V2SFmode, operands[0], operands[1]))
3892 DONE;
3893})
3894
3895(define_insn "movv2sf_hardfloat_64bit"
3896 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
3897 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
3898 "TARGET_PAIRED_SINGLE_FLOAT
3899 && TARGET_64BIT
3900 && (register_operand (operands[0], V2SFmode)
3901 || reg_or_0_operand (operands[1], V2SFmode))"
3902 { return mips_output_move (operands[0], operands[1]); }
3903 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store")
3904 (set_attr "mode" "SF")
3905 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
3906
3907;; The HI and LO registers are not truly independent. If we move an mthi
3908;; instruction before an mflo instruction, it will make the result of the
3909;; mflo unpredictable. The same goes for mtlo and mfhi.
3910;;
3911;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
3912;; Operand 1 is the register we want, operand 2 is the other one.
3913;;
3914;; When generating VR4120 or VR4130 code, we use macc{,hi} and
3915;; dmacc{,hi} instead of mfhi and mflo. This avoids both the normal
3916;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
3917
3918(define_expand "mfhilo_<mode>"
3919 [(set (match_operand:GPR 0 "register_operand")
3920 (unspec:GPR [(match_operand:GPR 1 "register_operand")
3921 (match_operand:GPR 2 "register_operand")]
3922 UNSPEC_MFHILO))])
3923
3924(define_insn "*mfhilo_<mode>"
3925 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3926 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3927 (match_operand:GPR 2 "register_operand" "l,h")]
3928 UNSPEC_MFHILO))]
3929 "!ISA_HAS_MACCHI"
3930 "mf%1\t%0"
3931 [(set_attr "type" "mfhilo")
3932 (set_attr "mode" "<MODE>")])
3933
3934(define_insn "*mfhilo_<mode>_macc"
3935 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3936 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
3937 (match_operand:GPR 2 "register_operand" "l,h")]
3938 UNSPEC_MFHILO))]
3939 "ISA_HAS_MACCHI"
3940{
3941 if (REGNO (operands[1]) == HI_REGNUM)
3942 return "<d>macchi\t%0,%.,%.";
3943 else
3944 return "<d>macc\t%0,%.,%.";
3945}
3946 [(set_attr "type" "mfhilo")
3947 (set_attr "mode" "<MODE>")])
3948
3949;; Patterns for loading or storing part of a paired floating point
3950;; register. We need them because odd-numbered floating-point registers
3951;; are not fully independent: see mips_split_64bit_move.
3952
3953;; Load the low word of operand 0 with operand 1.
3954(define_insn "load_df_low"
3955 [(set (match_operand:DF 0 "register_operand" "=f,f")
3956 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
3957 UNSPEC_LOAD_DF_LOW))]
3958 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3959{
3960 operands[0] = mips_subword (operands[0], 0);
3961 return mips_output_move (operands[0], operands[1]);
3962}
3963 [(set_attr "type" "xfer,fpload")
3964 (set_attr "mode" "SF")])
3965
3966;; Load the high word of operand 0 from operand 1, preserving the value
3967;; in the low word.
3968(define_insn "load_df_high"
3969 [(set (match_operand:DF 0 "register_operand" "=f,f")
3970 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
3971 (match_operand:DF 2 "register_operand" "0,0")]
3972 UNSPEC_LOAD_DF_HIGH))]
3973 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3974{
3975 operands[0] = mips_subword (operands[0], 1);
3976 return mips_output_move (operands[0], operands[1]);
3977}
3978 [(set_attr "type" "xfer,fpload")
3979 (set_attr "mode" "SF")])
3980
3981;; Store the high word of operand 1 in operand 0. The corresponding
3982;; low-word move is done in the normal way.
3983(define_insn "store_df_high"
3984 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3985 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
3986 UNSPEC_STORE_DF_HIGH))]
3987 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
3988{
3989 operands[1] = mips_subword (operands[1], 1);
3990 return mips_output_move (operands[0], operands[1]);
3991}
3992 [(set_attr "type" "xfer,fpstore")
3993 (set_attr "mode" "SF")])
3994
3995;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
3996;; of _gp from the start of this function. Operand 1 is the incoming
3997;; function address.
3998(define_insn_and_split "loadgp"
3999 [(unspec_volatile [(match_operand 0 "" "")
4000 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4001 "mips_current_loadgp_style () == LOADGP_NEWABI"
4002 "#"
4003 ""
4004 [(set (match_dup 2) (match_dup 3))
4005 (set (match_dup 2) (match_dup 4))
4006 (set (match_dup 2) (match_dup 5))]
4007{
4008 operands[2] = pic_offset_table_rtx;
4009 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4010 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4011 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4012}
4013 [(set_attr "length" "12")])
4014
4015;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
4016(define_insn_and_split "loadgp_noshared"
4017 [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
4018 "mips_current_loadgp_style () == LOADGP_ABSOLUTE"
4019 "#"
4020 ""
4021 [(const_int 0)]
4022{
4023 emit_move_insn (pic_offset_table_rtx, operands[0]);
4024 DONE;
4025}
4026 [(set_attr "length" "8")])
4027
4028;; The use of gp is hidden when not using explicit relocations.
4029;; This blockage instruction prevents the gp load from being
4030;; scheduled after an implicit use of gp. It also prevents
4031;; the load from being deleted as dead.
4032(define_insn "loadgp_blockage"
4033 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4034 ""
4035 ""
4036 [(set_attr "type" "unknown")
4037 (set_attr "mode" "none")
4038 (set_attr "length" "0")])
4039
4040;; Emit a .cprestore directive, which normally expands to a single store
4041;; instruction. Note that we continue to use .cprestore for explicit reloc
4042;; code so that jals inside inline asms will work correctly.
4043(define_insn "cprestore"
4044 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")]
4045 UNSPEC_CPRESTORE)]
4046 ""
4047{
4048 if (set_nomacro && which_alternative == 1)
4049 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
4050 else
4051 return ".cprestore\t%0";
4052}
4053 [(set_attr "type" "store")
4054 (set_attr "length" "4,12")])
4055
4056;; Block moves, see mips.c for more details.
4057;; Argument 0 is the destination
4058;; Argument 1 is the source
4059;; Argument 2 is the length
4060;; Argument 3 is the alignment
4061
4062(define_expand "movmemsi"
4063 [(parallel [(set (match_operand:BLK 0 "general_operand")
4064 (match_operand:BLK 1 "general_operand"))
4065 (use (match_operand:SI 2 ""))
4066 (use (match_operand:SI 3 "const_int_operand"))])]
4067 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4068{
4069 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4070 DONE;
4071 else
4072 FAIL;
4073})
4074
4075;;
4076;; ....................
4077;;
4078;; SHIFTS
4079;;
4080;; ....................
4081
4082(define_expand "<optab><mode>3"
4083 [(set (match_operand:GPR 0 "register_operand")
4084 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4085 (match_operand:SI 2 "arith_operand")))]
4086 ""
4087{
4088 /* On the mips16, a shift of more than 8 is a four byte instruction,
4089 so, for a shift between 8 and 16, it is just as fast to do two
4090 shifts of 8 or less. If there is a lot of shifting going on, we
4091 may win in CSE. Otherwise combine will put the shifts back
4092 together again. This can be called by function_arg, so we must
4093 be careful not to allocate a new register if we've reached the
4094 reload pass. */
4095 if (TARGET_MIPS16
4096 && optimize
4097 && GET_CODE (operands[2]) == CONST_INT
4098 && INTVAL (operands[2]) > 8
4099 && INTVAL (operands[2]) <= 16
4100 && !reload_in_progress
4101 && !reload_completed)
4102 {
4103 rtx temp = gen_reg_rtx (<MODE>mode);
4104
4105 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
4106 emit_insn (gen_<optab><mode>3 (operands[0], temp,
4107 GEN_INT (INTVAL (operands[2]) - 8)));
4108 DONE;
4109 }
4110})
4111
4112(define_insn "*<optab><mode>3"
4113 [(set (match_operand:GPR 0 "register_operand" "=d")
4114 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
4115 (match_operand:SI 2 "arith_operand" "dI")))]
4116 "!TARGET_MIPS16"
4117{
4118 if (GET_CODE (operands[2]) == CONST_INT)
4119 operands[2] = GEN_INT (INTVAL (operands[2])
4120 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
4121
4122 return "<d><insn>\t%0,%1,%2";
4123}
4124 [(set_attr "type" "shift")
4125 (set_attr "mode" "<MODE>")])
4126
4127(define_insn "*<optab>si3_extend"
4128 [(set (match_operand:DI 0 "register_operand" "=d")
4129 (sign_extend:DI
4130 (any_shift:SI (match_operand:SI 1 "register_operand" "d")
4131 (match_operand:SI 2 "arith_operand" "dI"))))]
4132 "TARGET_64BIT && !TARGET_MIPS16"
4133{
4134 if (GET_CODE (operands[2]) == CONST_INT)
4135 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4136
4137 return "<insn>\t%0,%1,%2";
4138}
4139 [(set_attr "type" "shift")
4140 (set_attr "mode" "SI")])
4141
4142(define_insn "*<optab>si3_mips16"
4143 [(set (match_operand:SI 0 "register_operand" "=d,d")
4144 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
4145 (match_operand:SI 2 "arith_operand" "d,I")))]
4146 "TARGET_MIPS16"
4147{
4148 if (which_alternative == 0)
4149 return "<insn>\t%0,%2";
4150
4151 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4152 return "<insn>\t%0,%1,%2";
4153}
4154 [(set_attr "type" "shift")
4155 (set_attr "mode" "SI")
4156 (set_attr_alternative "length"
4157 [(const_int 4)
4158 (if_then_else (match_operand 2 "m16_uimm3_b")
4159 (const_int 4)
4160 (const_int 8))])])
4161
4162;; We need separate DImode MIPS16 patterns because of the irregularity
4163;; of right shifts.
4164(define_insn "*ashldi3_mips16"
4165 [(set (match_operand:DI 0 "register_operand" "=d,d")
4166 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
4167 (match_operand:SI 2 "arith_operand" "d,I")))]
4168 "TARGET_64BIT && TARGET_MIPS16"
4169{
4170 if (which_alternative == 0)
4171 return "dsll\t%0,%2";
4172
4173 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4174 return "dsll\t%0,%1,%2";
4175}
4176 [(set_attr "type" "shift")
4177 (set_attr "mode" "DI")
4178 (set_attr_alternative "length"
4179 [(const_int 4)
4180 (if_then_else (match_operand 2 "m16_uimm3_b")
4181 (const_int 4)
4182 (const_int 8))])])
4183
4184(define_insn "*ashrdi3_mips16"
4185 [(set (match_operand:DI 0 "register_operand" "=d,d")
4186 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4187 (match_operand:SI 2 "arith_operand" "d,I")))]
4188 "TARGET_64BIT && TARGET_MIPS16"
4189{
4190 if (GET_CODE (operands[2]) == CONST_INT)
4191 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4192
4193 return "dsra\t%0,%2";
4194}
4195 [(set_attr "type" "shift")
4196 (set_attr "mode" "DI")
4197 (set_attr_alternative "length"
4198 [(const_int 4)
4199 (if_then_else (match_operand 2 "m16_uimm3_b")
4200 (const_int 4)
4201 (const_int 8))])])
4202
4203(define_insn "*lshrdi3_mips16"
4204 [(set (match_operand:DI 0 "register_operand" "=d,d")
4205 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
4206 (match_operand:SI 2 "arith_operand" "d,I")))]
4207 "TARGET_64BIT && TARGET_MIPS16"
4208{
4209 if (GET_CODE (operands[2]) == CONST_INT)
4210 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4211
4212 return "dsrl\t%0,%2";
4213}
4214 [(set_attr "type" "shift")
4215 (set_attr "mode" "DI")
4216 (set_attr_alternative "length"
4217 [(const_int 4)
4218 (if_then_else (match_operand 2 "m16_uimm3_b")
4219 (const_int 4)
4220 (const_int 8))])])
4221
4222;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4223
4224(define_split
4225 [(set (match_operand:GPR 0 "register_operand")
4226 (any_shift:GPR (match_operand:GPR 1 "register_operand")
4227 (match_operand:GPR 2 "const_int_operand")))]
4228 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4229 && GET_CODE (operands[2]) == CONST_INT
4230 && INTVAL (operands[2]) > 8
4231 && INTVAL (operands[2]) <= 16"
4232 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
4233 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
4234 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4235
4236;; If we load a byte on the mips16 as a bitfield, the resulting
4237;; sequence of instructions is too complicated for combine, because it
4238;; involves four instructions: a load, a shift, a constant load into a
4239;; register, and an and (the key problem here is that the mips16 does
4240;; not have and immediate). We recognize a shift of a load in order
4241;; to make it simple enough for combine to understand.
4242;;
4243;; The length here is the worst case: the length of the split version
4244;; will be more accurate.
4245(define_insn_and_split ""
4246 [(set (match_operand:SI 0 "register_operand" "=d")
4247 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4248 (match_operand:SI 2 "immediate_operand" "I")))]
4249 "TARGET_MIPS16"
4250 "#"
4251 ""
4252 [(set (match_dup 0) (match_dup 1))
4253 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
4254 ""
4255 [(set_attr "type" "load")
4256 (set_attr "mode" "SI")
4257 (set_attr "length" "16")])
4258
4259(define_insn "rotr<mode>3"
4260 [(set (match_operand:GPR 0 "register_operand" "=d")
4261 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
4262 (match_operand:SI 2 "arith_operand" "dI")))]
4263 "ISA_HAS_ROTR_<MODE>"
4264{
4265 if (GET_CODE (operands[2]) == CONST_INT)
4266 gcc_assert (INTVAL (operands[2]) >= 0
4267 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
4268
4269 return "<d>ror\t%0,%1,%2";
4270}
4271 [(set_attr "type" "shift")
4272 (set_attr "mode" "<MODE>")])
4273
4274;;
4275;; ....................
4276;;
4277;; COMPARISONS
4278;;
4279;; ....................
4280
4281;; Flow here is rather complex:
4282;;
4283;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
4284;; into cmp_operands[] but generates no RTL.
4285;;
4286;; 2) The appropriate branch define_expand is called, which then
4287;; creates the appropriate RTL for the comparison and branch.
4288;; Different CC modes are used, based on what type of branch is
4289;; done, so that we can constrain things appropriately. There
4290;; are assumptions in the rest of GCC that break if we fold the
4291;; operands into the branches for integer operations, and use cc0
4292;; for floating point, so we use the fp status register instead.
4293;; If needed, an appropriate temporary is created to hold the
4294;; of the integer compare.
4295
4296(define_expand "cmp<mode>"
4297 [(set (cc0)
4298 (compare:CC (match_operand:GPR 0 "register_operand")
4299 (match_operand:GPR 1 "nonmemory_operand")))]
4300 ""
4301{
4302 cmp_operands[0] = operands[0];
4303 cmp_operands[1] = operands[1];
4304 DONE;
4305})
4306
4307(define_expand "cmp<mode>"
4308 [(set (cc0)
4309 (compare:CC (match_operand:SCALARF 0 "register_operand")
4310 (match_operand:SCALARF 1 "register_operand")))]
4311 ""
4312{
4313 cmp_operands[0] = operands[0];
4314 cmp_operands[1] = operands[1];
4315 DONE;
4316})
4317
4318;;
4319;; ....................
4320;;
4321;; CONDITIONAL BRANCHES
4322;;
4323;; ....................
4324
4325;; Conditional branches on floating-point equality tests.
4326
4327(define_insn "*branch_fp"
4328 [(set (pc)
4329 (if_then_else
4330 (match_operator 0 "equality_operator"
4331 [(match_operand:CC 2 "register_operand" "z")
4332 (const_int 0)])
4333 (label_ref (match_operand 1 "" ""))
4334 (pc)))]
4335 "TARGET_HARD_FLOAT"
4336{
4337 return mips_output_conditional_branch (insn, operands,
4338 MIPS_BRANCH ("b%F0", "%Z2%1"),
4339 MIPS_BRANCH ("b%W0", "%Z2%1"));
4340}
4341 [(set_attr "type" "branch")
4342 (set_attr "mode" "none")])
4343
4344(define_insn "*branch_fp_inverted"
4345 [(set (pc)
4346 (if_then_else
4347 (match_operator 0 "equality_operator"
4348 [(match_operand:CC 2 "register_operand" "z")
4349 (const_int 0)])
4350 (pc)
4351 (label_ref (match_operand 1 "" ""))))]
4352 "TARGET_HARD_FLOAT"
4353{
4354 return mips_output_conditional_branch (insn, operands,
4355 MIPS_BRANCH ("b%W0", "%Z2%1"),
4356 MIPS_BRANCH ("b%F0", "%Z2%1"));
4357}
4358 [(set_attr "type" "branch")
4359 (set_attr "mode" "none")])
4360
4361;; Conditional branches on ordered comparisons with zero.
4362
4363(define_insn "*branch_order<mode>"
4364 [(set (pc)
4365 (if_then_else
4366 (match_operator 0 "order_operator"
4367 [(match_operand:GPR 2 "register_operand" "d")
4368 (const_int 0)])
4369 (label_ref (match_operand 1 "" ""))
4370 (pc)))]
4371 "!TARGET_MIPS16"
4372 { return mips_output_order_conditional_branch (insn, operands, false); }
4373 [(set_attr "type" "branch")
4374 (set_attr "mode" "none")])
4375
4376(define_insn "*branch_order<mode>_inverted"
4377 [(set (pc)
4378 (if_then_else
4379 (match_operator 0 "order_operator"
4380 [(match_operand:GPR 2 "register_operand" "d")
4381 (const_int 0)])
4382 (pc)
4383 (label_ref (match_operand 1 "" ""))))]
4384 "!TARGET_MIPS16"
4385 { return mips_output_order_conditional_branch (insn, operands, true); }
4386 [(set_attr "type" "branch")
4387 (set_attr "mode" "none")])
4388
4389;; Conditional branch on equality comparison.
4390
4391(define_insn "*branch_equality<mode>"
4392 [(set (pc)
4393 (if_then_else
4394 (match_operator 0 "equality_operator"
4395 [(match_operand:GPR 2 "register_operand" "d")
4396 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4397 (label_ref (match_operand 1 "" ""))
4398 (pc)))]
4399 "!TARGET_MIPS16"
4400{
4401 return mips_output_conditional_branch (insn, operands,
4402 MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
4403 MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
4404}
4405 [(set_attr "type" "branch")
4406 (set_attr "mode" "none")])
4407
4408(define_insn "*branch_equality<mode>_inverted"
4409 [(set (pc)
4410 (if_then_else
4411 (match_operator 0 "equality_operator"
4412 [(match_operand:GPR 2 "register_operand" "d")
4413 (match_operand:GPR 3 "reg_or_0_operand" "dJ")])
4414 (pc)
4415 (label_ref (match_operand 1 "" ""))))]
4416 "!TARGET_MIPS16"
4417{
4418 return mips_output_conditional_branch (insn, operands,
4419 MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
4420 MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
4421}
4422 [(set_attr "type" "branch")
4423 (set_attr "mode" "none")])
4424
4425;; MIPS16 branches
4426
4427(define_insn "*branch_equality<mode>_mips16"
4428 [(set (pc)
4429 (if_then_else
4430 (match_operator 0 "equality_operator"
4431 [(match_operand:GPR 1 "register_operand" "d,t")
4432 (const_int 0)])
4433 (match_operand 2 "pc_or_label_operand" "")
4434 (match_operand 3 "pc_or_label_operand" "")))]
4435 "TARGET_MIPS16"
4436{
4437 if (operands[2] != pc_rtx)
4438 {
4439 if (which_alternative == 0)
4440 return "b%C0z\t%1,%2";
4441 else
4442 return "bt%C0z\t%2";
4443 }
4444 else
4445 {
4446 if (which_alternative == 0)
4447 return "b%N0z\t%1,%3";
4448 else
4449 return "bt%N0z\t%3";
4450 }
4451}
4452 [(set_attr "type" "branch")
4453 (set_attr "mode" "none")
4454 (set_attr "length" "8")])
4455
4456(define_expand "b<code>"
4457 [(set (pc)
4458 (if_then_else (any_cond:CC (cc0)
4459 (const_int 0))
4460 (label_ref (match_operand 0 ""))
4461 (pc)))]
4462 ""
4463{
4464 gen_conditional_branch (operands, <CODE>);
4465 DONE;
4466})
4467
4468;; Used to implement built-in functions.
4469(define_expand "condjump"
4470 [(set (pc)
4471 (if_then_else (match_operand 0)
4472 (label_ref (match_operand 1))
4473 (pc)))])
4474
4475;;
4476;; ....................
4477;;
4478;; SETTING A REGISTER FROM A COMPARISON
4479;;
4480;; ....................
4481
4482(define_expand "seq"
4483 [(set (match_operand:SI 0 "register_operand")
4484 (eq:SI (match_dup 1)
4485 (match_dup 2)))]
4486 ""
4487 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
4488
4489(define_insn "*seq_<mode>"
4490 [(set (match_operand:GPR 0 "register_operand" "=d")
4491 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4492 (const_int 0)))]
4493 "!TARGET_MIPS16"
4494 "sltu\t%0,%1,1"
4495 [(set_attr "type" "slt")
4496 (set_attr "mode" "<MODE>")])
4497
4498(define_insn "*seq_<mode>_mips16"
4499 [(set (match_operand:GPR 0 "register_operand" "=t")
4500 (eq:GPR (match_operand:GPR 1 "register_operand" "d")
4501 (const_int 0)))]
4502 "TARGET_MIPS16"
4503 "sltu\t%1,1"
4504 [(set_attr "type" "slt")
4505 (set_attr "mode" "<MODE>")])
4506
4507;; "sne" uses sltu instructions in which the first operand is $0.
4508;; This isn't possible in mips16 code.
4509
4510(define_expand "sne"
4511 [(set (match_operand:SI 0 "register_operand")
4512 (ne:SI (match_dup 1)
4513 (match_dup 2)))]
4514 "!TARGET_MIPS16"
4515 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
4516
4517(define_insn "*sne_<mode>"
4518 [(set (match_operand:GPR 0 "register_operand" "=d")
4519 (ne:GPR (match_operand:GPR 1 "register_operand" "d")
4520 (const_int 0)))]
4521 "!TARGET_MIPS16"
4522 "sltu\t%0,%.,%1"
4523 [(set_attr "type" "slt")
4524 (set_attr "mode" "<MODE>")])
4525
4526(define_expand "sgt"
4527 [(set (match_operand:SI 0 "register_operand")
4528 (gt:SI (match_dup 1)
4529 (match_dup 2)))]
4530 ""
4531 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
4532
4533(define_insn "*sgt_<mode>"
4534 [(set (match_operand:GPR 0 "register_operand" "=d")
4535 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4536 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4537 "!TARGET_MIPS16"
4538 "slt\t%0,%z2,%1"
4539 [(set_attr "type" "slt")
4540 (set_attr "mode" "<MODE>")])
4541
4542(define_insn "*sgt_<mode>_mips16"
4543 [(set (match_operand:GPR 0 "register_operand" "=t")
4544 (gt:GPR (match_operand:GPR 1 "register_operand" "d")
4545 (match_operand:GPR 2 "register_operand" "d")))]
4546 "TARGET_MIPS16"
4547 "slt\t%2,%1"
4548 [(set_attr "type" "slt")
4549 (set_attr "mode" "<MODE>")])
4550
4551(define_expand "sge"
4552 [(set (match_operand:SI 0 "register_operand")
4553 (ge:SI (match_dup 1)
4554 (match_dup 2)))]
4555 ""
4556 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
4557
4558(define_insn "*sge_<mode>"
4559 [(set (match_operand:GPR 0 "register_operand" "=d")
4560 (ge:GPR (match_operand:GPR 1 "register_operand" "d")
4561 (const_int 1)))]
4562 "!TARGET_MIPS16"
4563 "slt\t%0,%.,%1"
4564 [(set_attr "type" "slt")
4565 (set_attr "mode" "<MODE>")])
4566
4567(define_expand "slt"
4568 [(set (match_operand:SI 0 "register_operand")
4569 (lt:SI (match_dup 1)
4570 (match_dup 2)))]
4571 ""
4572 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
4573
4574(define_insn "*slt_<mode>"
4575 [(set (match_operand:GPR 0 "register_operand" "=d")
4576 (lt:GPR (match_operand:GPR 1 "register_operand" "d")
4577 (match_operand:GPR 2 "arith_operand" "dI")))]
4578 "!TARGET_MIPS16"
4579 "slt\t%0,%1,%2"
4580 [(set_attr "type" "slt")
4581 (set_attr "mode" "<MODE>")])
4582
4583(define_insn "*slt_<mode>_mips16"
4584 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4585 (lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
4586 (match_operand:GPR 2 "arith_operand" "d,I")))]
4587 "TARGET_MIPS16"
4588 "slt\t%1,%2"
4589 [(set_attr "type" "slt")
4590 (set_attr "mode" "<MODE>")
4591 (set_attr_alternative "length"
4592 [(const_int 4)
4593 (if_then_else (match_operand 2 "m16_uimm8_1")
4594 (const_int 4)
4595 (const_int 8))])])
4596
4597(define_expand "sle"
4598 [(set (match_operand:SI 0 "register_operand")
4599 (le:SI (match_dup 1)
4600 (match_dup 2)))]
4601 ""
4602 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
4603
4604(define_insn "*sle_<mode>"
4605 [(set (match_operand:GPR 0 "register_operand" "=d")
4606 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4607 (match_operand:GPR 2 "sle_operand" "")))]
4608 "!TARGET_MIPS16"
4609{
4610 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4611 return "slt\t%0,%1,%2";
4612}
4613 [(set_attr "type" "slt")
4614 (set_attr "mode" "<MODE>")])
4615
4616(define_insn "*sle_<mode>_mips16"
4617 [(set (match_operand:GPR 0 "register_operand" "=t")
4618 (le:GPR (match_operand:GPR 1 "register_operand" "d")
4619 (match_operand:GPR 2 "sle_operand" "")))]
4620 "TARGET_MIPS16"
4621{
4622 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4623 return "slt\t%1,%2";
4624}
4625 [(set_attr "type" "slt")
4626 (set_attr "mode" "<MODE>")
4627 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4628 (const_int 4)
4629 (const_int 8)))])
4630
4631(define_expand "sgtu"
4632 [(set (match_operand:SI 0 "register_operand")
4633 (gtu:SI (match_dup 1)
4634 (match_dup 2)))]
4635 ""
4636 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
4637
4638(define_insn "*sgtu_<mode>"
4639 [(set (match_operand:GPR 0 "register_operand" "=d")
4640 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4641 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
4642 "!TARGET_MIPS16"
4643 "sltu\t%0,%z2,%1"
4644 [(set_attr "type" "slt")
4645 (set_attr "mode" "<MODE>")])
4646
4647(define_insn "*sgtu_<mode>_mips16"
4648 [(set (match_operand:GPR 0 "register_operand" "=t")
4649 (gtu:GPR (match_operand:GPR 1 "register_operand" "d")
4650 (match_operand:GPR 2 "register_operand" "d")))]
4651 "TARGET_MIPS16"
4652 "sltu\t%2,%1"
4653 [(set_attr "type" "slt")
4654 (set_attr "mode" "<MODE>")])
4655
4656(define_expand "sgeu"
4657 [(set (match_operand:SI 0 "register_operand")
4658 (geu:SI (match_dup 1)
4659 (match_dup 2)))]
4660 ""
4661 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
4662
4663(define_insn "*sge_<mode>"
4664 [(set (match_operand:GPR 0 "register_operand" "=d")
4665 (geu:GPR (match_operand:GPR 1 "register_operand" "d")
4666 (const_int 1)))]
4667 "!TARGET_MIPS16"
4668 "sltu\t%0,%.,%1"
4669 [(set_attr "type" "slt")
4670 (set_attr "mode" "<MODE>")])
4671
4672(define_expand "sltu"
4673 [(set (match_operand:SI 0 "register_operand")
4674 (ltu:SI (match_dup 1)
4675 (match_dup 2)))]
4676 ""
4677 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
4678
4679(define_insn "*sltu_<mode>"
4680 [(set (match_operand:GPR 0 "register_operand" "=d")
4681 (ltu:GPR (match_operand:GPR 1 "register_operand" "d")
4682 (match_operand:GPR 2 "arith_operand" "dI")))]
4683 "!TARGET_MIPS16"
4684 "sltu\t%0,%1,%2"
4685 [(set_attr "type" "slt")
4686 (set_attr "mode" "<MODE>")])
4687
4688(define_insn "*sltu_<mode>_mips16"
4689 [(set (match_operand:GPR 0 "register_operand" "=t,t")
4690 (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
4691 (match_operand:GPR 2 "arith_operand" "d,I")))]
4692 "TARGET_MIPS16"
4693 "sltu\t%1,%2"
4694 [(set_attr "type" "slt")
4695 (set_attr "mode" "<MODE>")
4696 (set_attr_alternative "length"
4697 [(const_int 4)
4698 (if_then_else (match_operand 2 "m16_uimm8_1")
4699 (const_int 4)
4700 (const_int 8))])])
4701
4702(define_expand "sleu"
4703 [(set (match_operand:SI 0 "register_operand")
4704 (leu:SI (match_dup 1)
4705 (match_dup 2)))]
4706 ""
4707 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
4708
4709(define_insn "*sleu_<mode>"
4710 [(set (match_operand:GPR 0 "register_operand" "=d")
4711 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4712 (match_operand:GPR 2 "sleu_operand" "")))]
4713 "!TARGET_MIPS16"
4714{
4715 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4716 return "sltu\t%0,%1,%2";
4717}
4718 [(set_attr "type" "slt")
4719 (set_attr "mode" "<MODE>")])
4720
4721(define_insn "*sleu_<mode>_mips16"
4722 [(set (match_operand:GPR 0 "register_operand" "=t")
4723 (leu:GPR (match_operand:GPR 1 "register_operand" "d")
4724 (match_operand:GPR 2 "sleu_operand" "")))]
4725 "TARGET_MIPS16"
4726{
4727 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
4728 return "sltu\t%1,%2";
4729}
4730 [(set_attr "type" "slt")
4731 (set_attr "mode" "<MODE>")
4732 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
4733 (const_int 4)
4734 (const_int 8)))])
4735
4736;;
4737;; ....................
4738;;
4739;; FLOATING POINT COMPARISONS
4740;;
4741;; ....................
4742
4743(define_insn "s<code>_<mode>"
4744 [(set (match_operand:CC 0 "register_operand" "=z")
4745 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4746 (match_operand:SCALARF 2 "register_operand" "f")))]
4747 ""
4748 "c.<fcond>.<fmt>\t%Z0%1,%2"
4749 [(set_attr "type" "fcmp")
4750 (set_attr "mode" "FPSW")])
4751
4752(define_insn "s<code>_<mode>"
4753 [(set (match_operand:CC 0 "register_operand" "=z")
4754 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
4755 (match_operand:SCALARF 2 "register_operand" "f")))]
4756 ""
4757 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1"
4758 [(set_attr "type" "fcmp")
4759 (set_attr "mode" "FPSW")])
4760
4761;;
4762;; ....................
4763;;
4764;; UNCONDITIONAL BRANCHES
4765;;
4766;; ....................
4767
4768;; Unconditional branches.
4769
4770(define_insn "jump"
4771 [(set (pc)
4772 (label_ref (match_operand 0 "" "")))]
4773 "!TARGET_MIPS16"
4774{
4775 if (flag_pic)
4776 {
4777 if (get_attr_length (insn) <= 8)
4778 return "%*b\t%l0%/";
4779 else
4780 {
4781 output_asm_insn (mips_output_load_label (), operands);
4782 return "%*jr\t%@%/%]";
4783 }
4784 }
4785 else
4786 return "%*j\t%l0%/";
4787}
4788 [(set_attr "type" "jump")
4789 (set_attr "mode" "none")
4790 (set (attr "length")
4791 ;; We can't use `j' when emitting PIC. Emit a branch if it's
4792 ;; in range, otherwise load the address of the branch target into
4793 ;; $at and then jump to it.
4794 (if_then_else
4795 (ior (eq (symbol_ref "flag_pic") (const_int 0))
4796 (lt (abs (minus (match_dup 0)
4797 (plus (pc) (const_int 4))))
4798 (const_int 131072)))
4799 (const_int 4) (const_int 16)))])
4800
4801;; We need a different insn for the mips16, because a mips16 branch
4802;; does not have a delay slot.
4803
4804(define_insn ""
4805 [(set (pc)
4806 (label_ref (match_operand 0 "" "")))]
4807 "TARGET_MIPS16"
4808 "b\t%l0"
4809 [(set_attr "type" "branch")
4810 (set_attr "mode" "none")
4811 (set_attr "length" "8")])
4812
4813(define_expand "indirect_jump"
4814 [(set (pc) (match_operand 0 "register_operand"))]
4815 ""
4816{
4817 operands[0] = force_reg (Pmode, operands[0]);
4818 if (Pmode == SImode)
4819 emit_jump_insn (gen_indirect_jumpsi (operands[0]));
4820 else
4821 emit_jump_insn (gen_indirect_jumpdi (operands[0]));
4822 DONE;
4823})
4824
4825(define_insn "indirect_jump<mode>"
4826 [(set (pc) (match_operand:P 0 "register_operand" "d"))]
4827 ""
4828 "%*j\t%0%/"
4829 [(set_attr "type" "jump")
4830 (set_attr "mode" "none")])
4831
4832(define_expand "tablejump"
4833 [(set (pc)
4834 (match_operand 0 "register_operand"))
4835 (use (label_ref (match_operand 1 "")))]
4836 ""
4837{
4838 if (TARGET_MIPS16)
4839 operands[0] = expand_binop (Pmode, add_optab,
4840 convert_to_mode (Pmode, operands[0], false),
4841 gen_rtx_LABEL_REF (Pmode, operands[1]),
4842 0, 0, OPTAB_WIDEN);
4843 else if (TARGET_GPWORD)
4844 operands[0] = expand_binop (Pmode, add_optab, operands[0],
4845 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
4846
4847 if (Pmode == SImode)
4848 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
4849 else
4850 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
4851 DONE;
4852})
4853
4854(define_insn "tablejump<mode>"
4855 [(set (pc)
4856 (match_operand:P 0 "register_operand" "d"))
4857 (use (label_ref (match_operand 1 "" "")))]
4858 ""
4859 "%*j\t%0%/"
4860 [(set_attr "type" "jump")
4861 (set_attr "mode" "none")])
4862
4863;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
4864;; While it is possible to either pull it off the stack (in the
4865;; o32 case) or recalculate it given t9 and our target label,
4866;; it takes 3 or 4 insns to do so.
4867
4868(define_expand "builtin_setjmp_setup"
4869 [(use (match_operand 0 "register_operand"))]
4870 "TARGET_ABICALLS"
4871{
4872 rtx addr;
4873
4874 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
4875 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
4876 DONE;
4877})
4878
4879;; Restore the gp that we saved above. Despite the earlier comment, it seems
4880;; that older code did recalculate the gp from $25. Continue to jump through
4881;; $25 for compatibility (we lose nothing by doing so).
4882
4883(define_expand "builtin_longjmp"
4884 [(use (match_operand 0 "register_operand"))]
4885 "TARGET_ABICALLS"
4886{
4887 /* The elements of the buffer are, in order: */
4888 int W = GET_MODE_SIZE (Pmode);
4889 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
4890 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
4891 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
4892 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
4893 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
4894 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
4895 The target is bound to be using $28 as the global pointer
4896 but the current function might not be. */
4897 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
4898
4899 /* This bit is similar to expand_builtin_longjmp except that it
4900 restores $gp as well. */
4901 emit_move_insn (hard_frame_pointer_rtx, fp);
4902 emit_move_insn (pv, lab);
4903 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
4904 emit_move_insn (gp, gpv);
4905 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
4906 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
4907 emit_insn (gen_rtx_USE (VOIDmode, gp));
4908 emit_indirect_jump (pv);
4909 DONE;
4910})
4911
4912;;
4913;; ....................
4914;;
4915;; Function prologue/epilogue
4916;;
4917;; ....................
4918;;
4919
4920(define_expand "prologue"
4921 [(const_int 1)]
4922 ""
4923{
4924 mips_expand_prologue ();
4925 DONE;
4926})
4927
4928;; Block any insns from being moved before this point, since the
4929;; profiling call to mcount can use various registers that aren't
4930;; saved or used to pass arguments.
4931
4932(define_insn "blockage"
4933 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4934 ""
4935 ""
4936 [(set_attr "type" "unknown")
4937 (set_attr "mode" "none")
4938 (set_attr "length" "0")])
4939
4940(define_expand "epilogue"
4941 [(const_int 2)]
4942 ""
4943{
4944 mips_expand_epilogue (false);
4945 DONE;
4946})
4947
4948(define_expand "sibcall_epilogue"
4949 [(const_int 2)]
4950 ""
4951{
4952 mips_expand_epilogue (true);
4953 DONE;
4954})
4955
4956;; Trivial return. Make it look like a normal return insn as that
4957;; allows jump optimizations to work better.
4958
4959(define_insn "return"
4960 [(return)]
4961 "mips_can_use_return_insn ()"
4962 "%*j\t$31%/"
4963 [(set_attr "type" "jump")
4964 (set_attr "mode" "none")])
4965
4966;; Normal return.
4967
4968(define_insn "return_internal"
4969 [(return)
4970 (use (match_operand 0 "pmode_register_operand" ""))]
4971 ""
4972 "%*j\t%0%/"
4973 [(set_attr "type" "jump")
4974 (set_attr "mode" "none")])
4975
4976;; This is used in compiling the unwind routines.
4977(define_expand "eh_return"
4978 [(use (match_operand 0 "general_operand"))]
4979 ""
4980{
4981 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
4982
4983 if (GET_MODE (operands[0]) != gpr_mode)
4984 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
4985 if (TARGET_64BIT)
4986 emit_insn (gen_eh_set_lr_di (operands[0]));
4987 else
4988 emit_insn (gen_eh_set_lr_si (operands[0]));
4989
4990 DONE;
4991})
4992
4993;; Clobber the return address on the stack. We can't expand this
4994;; until we know where it will be put in the stack frame.
4995
4996(define_insn "eh_set_lr_si"
4997 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
4998 (clobber (match_scratch:SI 1 "=&d"))]
4999 "! TARGET_64BIT"
5000 "#")
5001
5002(define_insn "eh_set_lr_di"
5003 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
5004 (clobber (match_scratch:DI 1 "=&d"))]
5005 "TARGET_64BIT"
5006 "#")
5007
5008(define_split
5009 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
5010 (clobber (match_scratch 1))]
5011 "reload_completed && !TARGET_DEBUG_D_MODE"
5012 [(const_int 0)]
5013{
5014 mips_set_return_address (operands[0], operands[1]);
5015 DONE;
5016})
5017
5018(define_insn_and_split "exception_receiver"
5019 [(set (reg:SI 28)
5020 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
5021 "TARGET_ABICALLS && TARGET_OLDABI"
5022 "#"
5023 "&& reload_completed"
5024 [(const_int 0)]
5025{
5026 mips_restore_gp ();
5027 DONE;
5028}
5029 [(set_attr "type" "load")
5030 (set_attr "length" "12")])
5031
5032;;
5033;; ....................
5034;;
5035;; FUNCTION CALLS
5036;;
5037;; ....................
5038
5039;; Instructions to load a call address from the GOT. The address might
5040;; point to a function or to a lazy binding stub. In the latter case,
5041;; the stub will use the dynamic linker to resolve the function, which
5042;; in turn will change the GOT entry to point to the function's real
5043;; address.
5044;;
5045;; This means that every call, even pure and constant ones, can
5046;; potentially modify the GOT entry. And once a stub has been called,
5047;; we must not call it again.
5048;;
5049;; We represent this restriction using an imaginary fixed register that
5050;; acts like a GOT version number. By making the register call-clobbered,
5051;; we tell the target-independent code that the address could be changed
5052;; by any call insn.
5053(define_insn "load_call<mode>"
5054 [(set (match_operand:P 0 "register_operand" "=c")
5055 (unspec:P [(match_operand:P 1 "register_operand" "r")
5056 (match_operand:P 2 "immediate_operand" "")
5057 (reg:P FAKE_CALL_REGNO)]
5058 UNSPEC_LOAD_CALL))]
5059 "TARGET_ABICALLS"
5060 "<load>\t%0,%R2(%1)"
5061 [(set_attr "type" "load")
5062 (set_attr "mode" "<MODE>")
5063 (set_attr "length" "4")])
5064
5065;; Sibling calls. All these patterns use jump instructions.
5066
5067;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
5068;; addresses if a direct jump is acceptable. Since the 'S' constraint
5069;; is defined in terms of call_insn_operand, the same is true of the
5070;; constraints.
5071
5072;; When we use an indirect jump, we need a register that will be
5073;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
5074;; use $25 for this purpose -- and $25 is never clobbered by the
5075;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
5076
5077(define_expand "sibcall"
5078 [(parallel [(call (match_operand 0 "")
5079 (match_operand 1 ""))
5080 (use (match_operand 2 "")) ;; next_arg_reg
5081 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5082 "TARGET_SIBCALLS"
5083{
5084 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
5085 DONE;
5086})
5087
5088(define_insn "sibcall_internal"
5089 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
5090 (match_operand 1 "" ""))]
5091 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5092 { return MIPS_CALL ("j", operands, 0); }
5093 [(set_attr "type" "call")])
5094
5095(define_expand "sibcall_value"
5096 [(parallel [(set (match_operand 0 "")
5097 (call (match_operand 1 "")
5098 (match_operand 2 "")))
5099 (use (match_operand 3 ""))])] ;; next_arg_reg
5100 "TARGET_SIBCALLS"
5101{
5102 mips_expand_call (operands[0], XEXP (operands[1], 0),
5103 operands[2], operands[3], true);
5104 DONE;
5105})
5106
5107(define_insn "sibcall_value_internal"
5108 [(set (match_operand 0 "register_operand" "=df,df")
5109 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5110 (match_operand 2 "" "")))]
5111 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5112 { return MIPS_CALL ("j", operands, 1); }
5113 [(set_attr "type" "call")])
5114
5115(define_insn "sibcall_value_multiple_internal"
5116 [(set (match_operand 0 "register_operand" "=df,df")
5117 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
5118 (match_operand 2 "" "")))
5119 (set (match_operand 3 "register_operand" "=df,df")
5120 (call (mem:SI (match_dup 1))
5121 (match_dup 2)))]
5122 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
5123 { return MIPS_CALL ("j", operands, 1); }
5124 [(set_attr "type" "call")])
5125
5126(define_expand "call"
5127 [(parallel [(call (match_operand 0 "")
5128 (match_operand 1 ""))
5129 (use (match_operand 2 "")) ;; next_arg_reg
5130 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
5131 ""
5132{
5133 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
5134 DONE;
5135})
5136
5137;; This instruction directly corresponds to an assembly-language "jal".
5138;; There are four cases:
5139;;
5140;; - -mno-abicalls:
5141;; Both symbolic and register destinations are OK. The pattern
5142;; always expands to a single mips instruction.
5143;;
5144;; - -mabicalls/-mno-explicit-relocs:
5145;; Again, both symbolic and register destinations are OK.
5146;; The call is treated as a multi-instruction black box.
5147;;
5148;; - -mabicalls/-mexplicit-relocs with n32 or n64:
5149;; Only "jal $25" is allowed. This expands to a single "jalr $25"
5150;; instruction.
5151;;
5152;; - -mabicalls/-mexplicit-relocs with o32 or o64:
5153;; Only "jal $25" is allowed. The call is actually two instructions:
5154;; "jalr $25" followed by an insn to reload $gp.
5155;;
5156;; In the last case, we can generate the individual instructions with
5157;; a define_split. There are several things to be wary of:
5158;;
5159;; - We can't expose the load of $gp before reload. If we did,
5160;; it might get removed as dead, but reload can introduce new
5161;; uses of $gp by rematerializing constants.
5162;;
5163;; - We shouldn't restore $gp after calls that never return.
5164;; It isn't valid to insert instructions between a noreturn
5165;; call and the following barrier.
5166;;
5167;; - The splitter deliberately changes the liveness of $gp. The unsplit
5168;; instruction preserves $gp and so have no effect on its liveness.
5169;; But once we generate the separate insns, it becomes obvious that
5170;; $gp is not live on entry to the call.
5171;;
5172;; ??? The operands[2] = insn check is a hack to make the original insn
5173;; available to the splitter.
5174(define_insn_and_split "call_internal"
5175 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
5176 (match_operand 1 "" ""))
5177 (clobber (reg:SI 31))]
5178 ""
5179 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
5180 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
5181 [(const_int 0)]
5182{
5183 emit_call_insn (gen_call_split (operands[0], operands[1]));
5184 if (!find_reg_note (operands[2], REG_NORETURN, 0))
5185 mips_restore_gp ();
5186 DONE;
5187}
5188 [(set_attr "jal" "indirect,direct")
5189 (set_attr "extended_mips16" "no,yes")])
5190
5191(define_insn "call_split"
5192 [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
5193 (match_operand 1 "" ""))
5194 (clobber (reg:SI 31))
5195 (clobber (reg:SI 28))]
5196 "TARGET_SPLIT_CALLS"
5197 { return MIPS_CALL ("jal", operands, 0); }
5198 [(set_attr "type" "call")])
5199
5200(define_expand "call_value"
5201 [(parallel [(set (match_operand 0 "")
5202 (call (match_operand 1 "")
5203 (match_operand 2 "")))
5204 (use (match_operand 3 ""))])] ;; next_arg_reg
5205 ""
5206{
5207 mips_expand_call (operands[0], XEXP (operands[1], 0),
5208 operands[2], operands[3], false);
5209 DONE;
5210})
5211
5212;; See comment for call_internal.
5213(define_insn_and_split "call_value_internal"
5214 [(set (match_operand 0 "register_operand" "=df,df")
5215 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5216 (match_operand 2 "" "")))
5217 (clobber (reg:SI 31))]
5218 ""
5219 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5220 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
5221 [(const_int 0)]
5222{
5223 emit_call_insn (gen_call_value_split (operands[0], operands[1],
5224 operands[2]));
5225 if (!find_reg_note (operands[3], REG_NORETURN, 0))
5226 mips_restore_gp ();
5227 DONE;
5228}
5229 [(set_attr "jal" "indirect,direct")
5230 (set_attr "extended_mips16" "no,yes")])
5231
5232(define_insn "call_value_split"
5233 [(set (match_operand 0 "register_operand" "=df")
5234 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5235 (match_operand 2 "" "")))
5236 (clobber (reg:SI 31))
5237 (clobber (reg:SI 28))]
5238 "TARGET_SPLIT_CALLS"
5239 { return MIPS_CALL ("jal", operands, 1); }
5240 [(set_attr "type" "call")])
5241
5242;; See comment for call_internal.
5243(define_insn_and_split "call_value_multiple_internal"
5244 [(set (match_operand 0 "register_operand" "=df,df")
5245 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
5246 (match_operand 2 "" "")))
5247 (set (match_operand 3 "register_operand" "=df,df")
5248 (call (mem:SI (match_dup 1))
5249 (match_dup 2)))
5250 (clobber (reg:SI 31))]
5251 ""
5252 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
5253 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
5254 [(const_int 0)]
5255{
5256 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
5257 operands[2], operands[3]));
5258 if (!find_reg_note (operands[4], REG_NORETURN, 0))
5259 mips_restore_gp ();
5260 DONE;
5261}
5262 [(set_attr "jal" "indirect,direct")
5263 (set_attr "extended_mips16" "no,yes")])
5264
5265(define_insn "call_value_multiple_split"
5266 [(set (match_operand 0 "register_operand" "=df")
5267 (call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
5268 (match_operand 2 "" "")))
5269 (set (match_operand 3 "register_operand" "=df")
5270 (call (mem:SI (match_dup 1))
5271 (match_dup 2)))
5272 (clobber (reg:SI 31))
5273 (clobber (reg:SI 28))]
5274 "TARGET_SPLIT_CALLS"
5275 { return MIPS_CALL ("jal", operands, 1); }
5276 [(set_attr "type" "call")])
5277
5278;; Call subroutine returning any type.
5279
5280(define_expand "untyped_call"
5281 [(parallel [(call (match_operand 0 "")
5282 (const_int 0))
5283 (match_operand 1 "")
5284 (match_operand 2 "")])]
5285 ""
5286{
5287 int i;
5288
5289 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
5290
5291 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5292 {
5293 rtx set = XVECEXP (operands[2], 0, i);
5294 emit_move_insn (SET_DEST (set), SET_SRC (set));
5295 }
5296
5297 emit_insn (gen_blockage ());
5298 DONE;
5299})
5300
5301;;
5302;; ....................
5303;;
5304;; MISC.
5305;;
5306;; ....................
5307;;
5308
5309
5310(define_insn "prefetch"
5311 [(prefetch (match_operand:QI 0 "address_operand" "p")
5312 (match_operand 1 "const_int_operand" "n")
5313 (match_operand 2 "const_int_operand" "n"))]
5314 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
5315{
5316 operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
5317 return "pref\t%1,%a0";
5318}
5319 [(set_attr "type" "prefetch")])
5320
5321(define_insn "*prefetch_indexed_<mode>"
5322 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d")
5323 (match_operand:P 1 "register_operand" "d"))
5324 (match_operand 2 "const_int_operand" "n")
5325 (match_operand 3 "const_int_operand" "n"))]
5326 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5327{
5328 operands[2] = mips_prefetch_cookie (operands[2], operands[3]);
5329 return "prefx\t%2,%1(%0)";
5330}
5331 [(set_attr "type" "prefetchx")])
5332
5333(define_insn "nop"
5334 [(const_int 0)]
5335 ""
5336 "%(nop%)"
5337 [(set_attr "type" "nop")
5338 (set_attr "mode" "none")])
5339
5340;; Like nop, but commented out when outside a .set noreorder block.
5341(define_insn "hazard_nop"
5342 [(const_int 1)]
5343 ""
5344 {
5345 if (set_noreorder)
5346 return "nop";
5347 else
5348 return "#nop";
5349 }
5350 [(set_attr "type" "nop")])
5351
5352;; MIPS4 Conditional move instructions.
5353
5354(define_insn "*mov<GPR:mode>_on_<MOVECC:mode>"
5355 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5356 (if_then_else:GPR
5357 (match_operator:MOVECC 4 "equality_operator"
5358 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5359 (const_int 0)])
5360 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0")
5361 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))]
5362 "ISA_HAS_CONDMOVE"
5363 "@
5364 mov%T4\t%0,%z2,%1
5365 mov%t4\t%0,%z3,%1"
5366 [(set_attr "type" "condmove")
5367 (set_attr "mode" "<GPR:MODE>")])
5368
5369(define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>"
5370 [(set (match_operand:SCALARF 0 "register_operand" "=f,f")
5371 (if_then_else:SCALARF
5372 (match_operator:MOVECC 4 "equality_operator"
5373 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>")
5374 (const_int 0)])
5375 (match_operand:SCALARF 2 "register_operand" "f,0")
5376 (match_operand:SCALARF 3 "register_operand" "0,f")))]
5377 "ISA_HAS_CONDMOVE"
5378 "@
5379 mov%T4.<fmt>\t%0,%2,%1
5380 mov%t4.<fmt>\t%0,%3,%1"
5381 [(set_attr "type" "condmove")
5382 (set_attr "mode" "<SCALARF:MODE>")])
5383
5384;; These are the main define_expand's used to make conditional moves.
5385
5386(define_expand "mov<mode>cc"
5387 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5388 (set (match_operand:GPR 0 "register_operand")
5389 (if_then_else:GPR (match_dup 5)
5390 (match_operand:GPR 2 "reg_or_0_operand")
5391 (match_operand:GPR 3 "reg_or_0_operand")))]
5392 "ISA_HAS_CONDMOVE"
5393{
5394 gen_conditional_move (operands);
5395 DONE;
5396})
5397
5398(define_expand "mov<mode>cc"
5399 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
5400 (set (match_operand:SCALARF 0 "register_operand")
5401 (if_then_else:SCALARF (match_dup 5)
5402 (match_operand:SCALARF 2 "register_operand")
5403 (match_operand:SCALARF 3 "register_operand")))]
5404 "ISA_HAS_CONDMOVE"
5405{
5406 gen_conditional_move (operands);
5407 DONE;
5408})
5409
5410;;
5411;; ....................
5412;;
5413;; mips16 inline constant tables
5414;;
5415;; ....................
5416;;
5417
5418(define_insn "consttable_int"
5419 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
5420 (match_operand 1 "const_int_operand" "")]
5421 UNSPEC_CONSTTABLE_INT)]
5422 "TARGET_MIPS16"
5423{
5424 assemble_integer (operands[0], INTVAL (operands[1]),
5425 BITS_PER_UNIT * INTVAL (operands[1]), 1);
5426 return "";
5427}
5428 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
5429
5430(define_insn "consttable_float"
5431 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
5432 UNSPEC_CONSTTABLE_FLOAT)]
5433 "TARGET_MIPS16"
5434{
5435 REAL_VALUE_TYPE d;
5436
5437 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
5438 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
5439 assemble_real (d, GET_MODE (operands[0]),
5440 GET_MODE_BITSIZE (GET_MODE (operands[0])));
5441 return "";
5442}
5443 [(set (attr "length")
5444 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
5445
5446(define_insn "align"
5447 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
5448 ""
5449 ".align\t%0"
5450 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
5451
5452(define_split
5453 [(match_operand 0 "small_data_pattern")]
5454 "reload_completed"
5455 [(match_dup 0)]
5456 { operands[0] = mips_rewrite_small_data (operands[0]); })
5457
5458; Thread-Local Storage
5459
5460; The TLS base pointer is accessed via "rdhwr $v1, $29". No current
5461; MIPS architecture defines this register, and no current
5462; implementation provides it; instead, any OS which supports TLS is
5463; expected to trap and emulate this instruction. rdhwr is part of the
5464; MIPS 32r2 specification, but we use it on any architecture because
5465; we expect it to be emulated. Use .set to force the assembler to
5466; accept it.
5467
5468(define_insn "tls_get_tp_<mode>"
5469 [(set (match_operand:P 0 "register_operand" "=v")
5470 (unspec:P [(const_int 0)]
5471 UNSPEC_TLS_GET_TP))]
5472 "HAVE_AS_TLS && !TARGET_MIPS16"
5473 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
5474 [(set_attr "type" "unknown")
5475 ; Since rdhwr always generates a trap for now, putting it in a delay
5476 ; slot would make the kernel's emulation of it much slower.
5477 (set_attr "can_delay" "no")
5478 (set_attr "mode" "<MODE>")])
5479
5480; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
5481
5482(include "mips-ps-3d.md")
5483
5484; The MIPS DSP Instructions.
5485
5486(include "mips-dsp.md")