cad6dbfdb4511f0429f4f9f80866467e93bf2cc4
[gcc.git] / gcc / config / mips / mips.md
1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
28
29 (define_constants
30 [(UNSPEC_LOAD_DF_LOW 0)
31 (UNSPEC_LOAD_DF_HIGH 1)
32 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_GET_FNADDR 3)
34 (UNSPEC_BLOCKAGE 4)
35 (UNSPEC_CPRESTORE 5)
36 (UNSPEC_EH_RECEIVER 6)
37 (UNSPEC_EH_RETURN 7)
38 (UNSPEC_CONSTTABLE_INT 8)
39 (UNSPEC_CONSTTABLE_FLOAT 9)
40 (UNSPEC_ALIGN 14)
41 (UNSPEC_HIGH 17)
42 (UNSPEC_LWL 18)
43 (UNSPEC_LWR 19)
44 (UNSPEC_SWL 20)
45 (UNSPEC_SWR 21)
46 (UNSPEC_LDL 22)
47 (UNSPEC_LDR 23)
48 (UNSPEC_SDL 24)
49 (UNSPEC_SDR 25)
50 (UNSPEC_LOADGP 26)
51 (UNSPEC_LOAD_CALL 27)
52 (UNSPEC_LOAD_GOT 28)
53 (UNSPEC_GP 29)
54 (UNSPEC_MFHILO 30)
55
56 (UNSPEC_ADDRESS_FIRST 100)
57
58 (FAKE_CALL_REGNO 79)])
59 \f
60 ;; ....................
61 ;;
62 ;; Attributes
63 ;;
64 ;; ....................
65
66 (define_attr "got" "unset,xgot_high,load"
67 (const_string "unset"))
68
69 ;; For jal instructions, this attribute is DIRECT when the target address
70 ;; is symbolic and INDIRECT when it is a register.
71 (define_attr "jal" "unset,direct,indirect"
72 (const_string "unset"))
73
74 ;; This attribute is YES if the instruction is a jal macro (not a
75 ;; real jal instruction).
76 ;;
77 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
78 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
79 ;; load the target address into $25.
80 (define_attr "jal_macro" "no,yes"
81 (cond [(eq_attr "jal" "direct")
82 (symbol_ref "TARGET_ABICALLS != 0")
83 (eq_attr "jal" "indirect")
84 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
85 (const_string "no")))
86
87 ;; Classification of each insn.
88 ;; branch conditional branch
89 ;; jump unconditional jump
90 ;; call unconditional call
91 ;; load load instruction(s)
92 ;; fpload floating point load
93 ;; fpidxload floating point indexed load
94 ;; store store instruction(s)
95 ;; fpstore floating point store
96 ;; fpidxstore floating point indexed store
97 ;; prefetch memory prefetch (register + offset)
98 ;; prefetchx memory indexed prefetch (register + register)
99 ;; condmove conditional moves
100 ;; xfer transfer to/from coprocessor
101 ;; mthilo transfer to hi/lo registers
102 ;; mfhilo transfer from hi/lo registers
103 ;; const load constant
104 ;; arith integer arithmetic and logical instructions
105 ;; shift integer shift instructions
106 ;; slt set less than instructions
107 ;; clz the clz and clo instructions
108 ;; trap trap if instructions
109 ;; imul integer multiply
110 ;; imadd integer multiply-add
111 ;; idiv integer divide
112 ;; fmove floating point register move
113 ;; fadd floating point add/subtract
114 ;; fmul floating point multiply
115 ;; fmadd floating point multiply-add
116 ;; fdiv floating point divide
117 ;; fabs floating point absolute value
118 ;; fneg floating point negation
119 ;; fcmp floating point compare
120 ;; fcvt floating point convert
121 ;; fsqrt floating point square root
122 ;; frsqrt floating point reciprocal square root
123 ;; multi multiword sequence (or user asm statements)
124 ;; nop no operation
125 (define_attr "type"
126 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
127 (cond [(eq_attr "jal" "!unset") (const_string "call")
128 (eq_attr "got" "load") (const_string "load")]
129 (const_string "unknown")))
130
131 ;; Main data type used by the insn
132 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
133 (const_string "unknown"))
134
135 ;; Is this an extended instruction in mips16 mode?
136 (define_attr "extended_mips16" "no,yes"
137 (const_string "no"))
138
139 ;; Length of instruction in bytes.
140 (define_attr "length" ""
141 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
142 ;; If a branch is outside this range, we have a choice of two
143 ;; sequences. For PIC, an out-of-range branch like:
144 ;;
145 ;; bne r1,r2,target
146 ;; dslot
147 ;;
148 ;; becomes the equivalent of:
149 ;;
150 ;; beq r1,r2,1f
151 ;; dslot
152 ;; la $at,target
153 ;; jr $at
154 ;; nop
155 ;; 1:
156 ;;
157 ;; where the load address can be up to three instructions long
158 ;; (lw, nop, addiu).
159 ;;
160 ;; The non-PIC case is similar except that we use a direct
161 ;; jump instead of an la/jr pair. Since the target of this
162 ;; jump is an absolute 28-bit bit address (the other bits
163 ;; coming from the address of the delay slot) this form cannot
164 ;; cross a 256MB boundary. We could provide the option of
165 ;; using la/jr in this case too, but we do not do so at
166 ;; present.
167 ;;
168 ;; Note that this value does not account for the delay slot
169 ;; instruction, whose length is added separately. If the RTL
170 ;; pattern has no explicit delay slot, mips_adjust_insn_length
171 ;; will add the length of the implicit nop. The values for
172 ;; forward and backward branches will be different as well.
173 (eq_attr "type" "branch")
174 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
175 (le (minus (pc) (match_dup 1)) (const_int 131068)))
176 (const_int 4)
177 (ne (symbol_ref "flag_pic") (const_int 0))
178 (const_int 24)
179 ] (const_int 12))
180
181 (eq_attr "got" "load")
182 (const_int 4)
183 (eq_attr "got" "xgot_high")
184 (const_int 8)
185
186 (eq_attr "type" "const")
187 (symbol_ref "mips_const_insns (operands[1]) * 4")
188 (eq_attr "type" "load,fpload,fpidxload")
189 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
190 (eq_attr "type" "store,fpstore,fpidxstore")
191 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
192
193 ;; In the worst case, a call macro will take 8 instructions:
194 ;;
195 ;; lui $25,%call_hi(FOO)
196 ;; addu $25,$25,$28
197 ;; lw $25,%call_lo(FOO)($25)
198 ;; nop
199 ;; jalr $25
200 ;; nop
201 ;; lw $gp,X($sp)
202 ;; nop
203 (eq_attr "jal_macro" "yes")
204 (const_int 32)
205
206 (and (eq_attr "extended_mips16" "yes")
207 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
208 (const_int 8)
209
210 ;; Various VR4120 errata require a nop to be inserted after a macc
211 ;; instruction. The assembler does this for us, so account for
212 ;; the worst-case length here.
213 (and (eq_attr "type" "imadd")
214 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
215 (const_int 8)
216
217 ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
218 ;; the result of the second one is missed. The assembler should work
219 ;; around this by inserting a nop after the first dmult.
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI")
222 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
223 (const_int 8)
224
225 (eq_attr "type" "idiv")
226 (symbol_ref "mips_idiv_insns () * 4")
227 ] (const_int 4)))
228
229 ;; Attribute describing the processor. This attribute must match exactly
230 ;; with the processor_type enumeration in mips.h.
231 (define_attr "cpu"
232 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
233 (const (symbol_ref "mips_tune")))
234
235 ;; The type of hardware hazard associated with this instruction.
236 ;; DELAY means that the next instruction cannot read the result
237 ;; of this one. HILO means that the next two instructions cannot
238 ;; write to HI or LO.
239 (define_attr "hazard" "none,delay,hilo"
240 (cond [(and (eq_attr "type" "load,fpload,fpidxload")
241 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
242 (const_string "delay")
243
244 (and (eq_attr "type" "xfer")
245 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
246 (const_string "delay")
247
248 (and (eq_attr "type" "fcmp")
249 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
250 (const_string "delay")
251
252 ;; The r4000 multiplication patterns include an mflo instruction.
253 (and (eq_attr "type" "imul")
254 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
255 (const_string "hilo")
256
257 (and (eq_attr "type" "mfhilo")
258 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
259 (const_string "hilo")]
260 (const_string "none")))
261
262 ;; Is it a single instruction?
263 (define_attr "single_insn" "no,yes"
264 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
265
266 ;; Can the instruction be put into a delay slot?
267 (define_attr "can_delay" "no,yes"
268 (if_then_else (and (eq_attr "type" "!branch,call,jump")
269 (and (eq_attr "hazard" "none")
270 (eq_attr "single_insn" "yes")))
271 (const_string "yes")
272 (const_string "no")))
273
274 ;; Attribute defining whether or not we can use the branch-likely instructions
275 (define_attr "branch_likely" "no,yes"
276 (const
277 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
278 (const_string "yes")
279 (const_string "no"))))
280
281 ;; True if an instruction might assign to hi or lo when reloaded.
282 ;; This is used by the TUNE_MACC_CHAINS code.
283 (define_attr "may_clobber_hilo" "no,yes"
284 (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
285 (const_string "yes")
286 (const_string "no")))
287
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290 [(set_attr "type" "multi")])
291 \f
292 ;; .........................
293 ;;
294 ;; Branch, call and jump delay slots
295 ;;
296 ;; .........................
297
298 (define_delay (and (eq_attr "type" "branch")
299 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
300 [(eq_attr "can_delay" "yes")
301 (nil)
302 (and (eq_attr "branch_likely" "yes")
303 (eq_attr "can_delay" "yes"))])
304
305 (define_delay (eq_attr "type" "jump")
306 [(eq_attr "can_delay" "yes")
307 (nil)
308 (nil)])
309
310 (define_delay (and (eq_attr "type" "call")
311 (eq_attr "jal_macro" "no"))
312 [(eq_attr "can_delay" "yes")
313 (nil)
314 (nil)])
315 \f
316 ;; Pipeline descriptions.
317 ;;
318 ;; generic.md provides a fallback for processors without a specific
319 ;; pipeline description. It is derived from the old define_function_unit
320 ;; version and uses the "alu" and "imuldiv" units declared below.
321 ;;
322 ;; Some of the processor-specific files are also derived from old
323 ;; define_function_unit descriptions and simply override the parts of
324 ;; generic.md that don't apply. The other processor-specific files
325 ;; are self-contained.
326 (define_automaton "alu,imuldiv")
327
328 (define_cpu_unit "alu" "alu")
329 (define_cpu_unit "imuldiv" "imuldiv")
330
331 (include "3000.md")
332 (include "4000.md")
333 (include "4100.md")
334 (include "4130.md")
335 (include "4300.md")
336 (include "4600.md")
337 (include "5000.md")
338 (include "5400.md")
339 (include "5500.md")
340 (include "6000.md")
341 (include "7000.md")
342 (include "9000.md")
343 (include "sb1.md")
344 (include "sr71k.md")
345 (include "generic.md")
346 \f
347 ;;
348 ;; ....................
349 ;;
350 ;; CONDITIONAL TRAPS
351 ;;
352 ;; ....................
353 ;;
354
355 (define_insn "trap"
356 [(trap_if (const_int 1) (const_int 0))]
357 ""
358 {
359 if (ISA_HAS_COND_TRAP)
360 return "teq\t$0,$0";
361 /* The IRIX 6 O32 assembler requires the first break operand. */
362 else if (TARGET_MIPS16 || !TARGET_GAS)
363 return "break 0";
364 else
365 return "break";
366 }
367 [(set_attr "type" "trap")])
368
369 (define_expand "conditional_trap"
370 [(trap_if (match_operator 0 "cmp_op"
371 [(match_dup 2) (match_dup 3)])
372 (match_operand 1 "const_int_operand"))]
373 "ISA_HAS_COND_TRAP"
374 {
375 if (operands[1] == const0_rtx)
376 {
377 mips_gen_conditional_trap (operands);
378 DONE;
379 }
380 else
381 FAIL;
382 })
383
384 (define_insn ""
385 [(trap_if (match_operator 0 "trap_cmp_op"
386 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
387 (match_operand:SI 2 "arith_operand" "dI")])
388 (const_int 0))]
389 "ISA_HAS_COND_TRAP"
390 "t%C0\t%z1,%z2"
391 [(set_attr "type" "trap")])
392
393 (define_insn ""
394 [(trap_if (match_operator 0 "trap_cmp_op"
395 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
396 (match_operand:DI 2 "arith_operand" "dI")])
397 (const_int 0))]
398 "TARGET_64BIT && ISA_HAS_COND_TRAP"
399 "t%C0\t%z1,%z2"
400 [(set_attr "type" "trap")])
401 \f
402 ;;
403 ;; ....................
404 ;;
405 ;; ADDITION
406 ;;
407 ;; ....................
408 ;;
409
410 (define_insn "adddf3"
411 [(set (match_operand:DF 0 "register_operand" "=f")
412 (plus:DF (match_operand:DF 1 "register_operand" "f")
413 (match_operand:DF 2 "register_operand" "f")))]
414 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
415 "add.d\t%0,%1,%2"
416 [(set_attr "type" "fadd")
417 (set_attr "mode" "DF")])
418
419 (define_insn "addsf3"
420 [(set (match_operand:SF 0 "register_operand" "=f")
421 (plus:SF (match_operand:SF 1 "register_operand" "f")
422 (match_operand:SF 2 "register_operand" "f")))]
423 "TARGET_HARD_FLOAT"
424 "add.s\t%0,%1,%2"
425 [(set_attr "type" "fadd")
426 (set_attr "mode" "SF")])
427
428 (define_expand "addsi3"
429 [(set (match_operand:SI 0 "register_operand")
430 (plus:SI (match_operand:SI 1 "reg_or_0_operand")
431 (match_operand:SI 2 "arith_operand")))]
432 ""
433 {
434 /* If a large stack adjustment was forced into a register, we may be
435 asked to generate rtx such as:
436
437 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
438
439 but no such instruction is available in mips16. Handle it by
440 using a temporary. */
441 if (TARGET_MIPS16
442 && REGNO (operands[0]) == STACK_POINTER_REGNUM
443 && ((GET_CODE (operands[1]) == REG
444 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
445 || GET_CODE (operands[2]) != CONST_INT))
446 {
447 rtx tmp = gen_reg_rtx (SImode);
448
449 emit_move_insn (tmp, operands[1]);
450 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
451 emit_move_insn (operands[0], tmp);
452 DONE;
453 }
454 })
455
456 (define_insn "addsi3_internal"
457 [(set (match_operand:SI 0 "register_operand" "=d,d")
458 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
459 (match_operand:SI 2 "arith_operand" "d,Q")))]
460 "!TARGET_MIPS16"
461 "@
462 addu\t%0,%z1,%2
463 addiu\t%0,%z1,%2"
464 [(set_attr "type" "arith")
465 (set_attr "mode" "SI")])
466
467 ;; For the mips16, we need to recognize stack pointer additions
468 ;; explicitly, since we don't have a constraint for $sp. These insns
469 ;; will be generated by the save_restore_insns functions.
470
471 (define_insn ""
472 [(set (reg:SI 29)
473 (plus:SI (reg:SI 29)
474 (match_operand:SI 0 "small_int" "I")))]
475 "TARGET_MIPS16"
476 "addu\t%$,%$,%0"
477 [(set_attr "type" "arith")
478 (set_attr "mode" "SI")
479 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
480 (const_int 4)
481 (const_int 8)))])
482
483 (define_insn ""
484 [(set (match_operand:SI 0 "register_operand" "=d")
485 (plus:SI (reg:SI 29)
486 (match_operand:SI 1 "small_int" "I")))]
487 "TARGET_MIPS16"
488 "addu\t%0,%$,%1"
489 [(set_attr "type" "arith")
490 (set_attr "mode" "SI")
491 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
492 (const_int 4)
493 (const_int 8)))])
494
495 (define_insn ""
496 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
497 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
498 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
499 "TARGET_MIPS16
500 && (GET_CODE (operands[1]) != REG
501 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
502 || M16_REG_P (REGNO (operands[1]))
503 || REGNO (operands[1]) == ARG_POINTER_REGNUM
504 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
505 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
506 && (GET_CODE (operands[2]) != REG
507 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
508 || M16_REG_P (REGNO (operands[2]))
509 || REGNO (operands[2]) == ARG_POINTER_REGNUM
510 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
511 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
512 {
513 if (REGNO (operands[0]) == REGNO (operands[1]))
514 return "addu\t%0,%2";
515 else
516 return "addu\t%0,%1,%2";
517 }
518 [(set_attr "type" "arith")
519 (set_attr "mode" "SI")
520 (set_attr_alternative "length"
521 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
522 (const_int 4)
523 (const_int 8))
524 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
525 (const_int 4)
526 (const_int 8))
527 (const_int 4)])])
528
529
530 ;; On the mips16, we can sometimes split an add of a constant which is
531 ;; a 4 byte instruction into two adds which are both 2 byte
532 ;; instructions. There are two cases: one where we are adding a
533 ;; constant plus a register to another register, and one where we are
534 ;; simply adding a constant to a register.
535
536 (define_split
537 [(set (match_operand:SI 0 "register_operand")
538 (plus:SI (match_dup 0)
539 (match_operand:SI 1 "const_int_operand")))]
540 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
541 && GET_CODE (operands[0]) == REG
542 && M16_REG_P (REGNO (operands[0]))
543 && GET_CODE (operands[1]) == CONST_INT
544 && ((INTVAL (operands[1]) > 0x7f
545 && INTVAL (operands[1]) <= 0x7f + 0x7f)
546 || (INTVAL (operands[1]) < - 0x80
547 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
548 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
549 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
550 {
551 HOST_WIDE_INT val = INTVAL (operands[1]);
552
553 if (val >= 0)
554 {
555 operands[1] = GEN_INT (0x7f);
556 operands[2] = GEN_INT (val - 0x7f);
557 }
558 else
559 {
560 operands[1] = GEN_INT (- 0x80);
561 operands[2] = GEN_INT (val + 0x80);
562 }
563 })
564
565 (define_split
566 [(set (match_operand:SI 0 "register_operand")
567 (plus:SI (match_operand:SI 1 "register_operand")
568 (match_operand:SI 2 "const_int_operand")))]
569 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
570 && GET_CODE (operands[0]) == REG
571 && M16_REG_P (REGNO (operands[0]))
572 && GET_CODE (operands[1]) == REG
573 && M16_REG_P (REGNO (operands[1]))
574 && REGNO (operands[0]) != REGNO (operands[1])
575 && GET_CODE (operands[2]) == CONST_INT
576 && ((INTVAL (operands[2]) > 0x7
577 && INTVAL (operands[2]) <= 0x7 + 0x7f)
578 || (INTVAL (operands[2]) < - 0x8
579 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
580 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
581 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
582 {
583 HOST_WIDE_INT val = INTVAL (operands[2]);
584
585 if (val >= 0)
586 {
587 operands[2] = GEN_INT (0x7);
588 operands[3] = GEN_INT (val - 0x7);
589 }
590 else
591 {
592 operands[2] = GEN_INT (- 0x8);
593 operands[3] = GEN_INT (val + 0x8);
594 }
595 })
596
597 (define_expand "adddi3"
598 [(set (match_operand:DI 0 "register_operand")
599 (plus:DI (match_operand:DI 1 "register_operand")
600 (match_operand:DI 2 "arith_operand")))]
601 "TARGET_64BIT"
602 {
603 /* If a large stack adjustment was forced into a register, we may be
604 asked to generate rtx such as:
605
606 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
607
608 but no such instruction is available in mips16. Handle it by
609 using a temporary. */
610 if (TARGET_MIPS16
611 && REGNO (operands[0]) == STACK_POINTER_REGNUM
612 && ((GET_CODE (operands[1]) == REG
613 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
614 || GET_CODE (operands[2]) != CONST_INT))
615 {
616 rtx tmp = gen_reg_rtx (DImode);
617
618 emit_move_insn (tmp, operands[1]);
619 emit_insn (gen_adddi3 (tmp, tmp, operands[2]));
620 emit_move_insn (operands[0], tmp);
621 DONE;
622 }
623 })
624
625 (define_insn "adddi3_internal"
626 [(set (match_operand:DI 0 "register_operand" "=d,d")
627 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
628 (match_operand:DI 2 "arith_operand" "d,Q")))]
629 "TARGET_64BIT && !TARGET_MIPS16"
630 "@
631 daddu\t%0,%z1,%2
632 daddiu\t%0,%z1,%2"
633 [(set_attr "type" "arith")
634 (set_attr "mode" "DI")])
635
636 ;; For the mips16, we need to recognize stack pointer additions
637 ;; explicitly, since we don't have a constraint for $sp. These insns
638 ;; will be generated by the save_restore_insns functions.
639
640 (define_insn ""
641 [(set (reg:DI 29)
642 (plus:DI (reg:DI 29)
643 (match_operand:DI 0 "small_int" "I")))]
644 "TARGET_MIPS16 && TARGET_64BIT"
645 "daddu\t%$,%$,%0"
646 [(set_attr "type" "arith")
647 (set_attr "mode" "DI")
648 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
649 (const_int 4)
650 (const_int 8)))])
651
652 (define_insn ""
653 [(set (match_operand:DI 0 "register_operand" "=d")
654 (plus:DI (reg:DI 29)
655 (match_operand:DI 1 "small_int" "I")))]
656 "TARGET_MIPS16 && TARGET_64BIT"
657 "daddu\t%0,%$,%1"
658 [(set_attr "type" "arith")
659 (set_attr "mode" "DI")
660 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
661 (const_int 4)
662 (const_int 8)))])
663
664 (define_insn ""
665 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
666 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
667 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
668 "TARGET_MIPS16 && TARGET_64BIT
669 && (GET_CODE (operands[1]) != REG
670 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
671 || M16_REG_P (REGNO (operands[1]))
672 || REGNO (operands[1]) == ARG_POINTER_REGNUM
673 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
674 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
675 && (GET_CODE (operands[2]) != REG
676 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
677 || M16_REG_P (REGNO (operands[2]))
678 || REGNO (operands[2]) == ARG_POINTER_REGNUM
679 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
680 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
681 {
682 if (REGNO (operands[0]) == REGNO (operands[1]))
683 return "daddu\t%0,%2";
684 else
685 return "daddu\t%0,%1,%2";
686 }
687 [(set_attr "type" "arith")
688 (set_attr "mode" "DI")
689 (set_attr_alternative "length"
690 [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
691 (const_int 4)
692 (const_int 8))
693 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
694 (const_int 4)
695 (const_int 8))
696 (const_int 4)])])
697
698
699 ;; On the mips16, we can sometimes split an add of a constant which is
700 ;; a 4 byte instruction into two adds which are both 2 byte
701 ;; instructions. There are two cases: one where we are adding a
702 ;; constant plus a register to another register, and one where we are
703 ;; simply adding a constant to a register.
704
705 (define_split
706 [(set (match_operand:DI 0 "register_operand")
707 (plus:DI (match_dup 0)
708 (match_operand:DI 1 "const_int_operand")))]
709 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
710 && GET_CODE (operands[0]) == REG
711 && M16_REG_P (REGNO (operands[0]))
712 && GET_CODE (operands[1]) == CONST_INT
713 && ((INTVAL (operands[1]) > 0xf
714 && INTVAL (operands[1]) <= 0xf + 0xf)
715 || (INTVAL (operands[1]) < - 0x10
716 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
717 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
718 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
719 {
720 HOST_WIDE_INT val = INTVAL (operands[1]);
721
722 if (val >= 0)
723 {
724 operands[1] = GEN_INT (0xf);
725 operands[2] = GEN_INT (val - 0xf);
726 }
727 else
728 {
729 operands[1] = GEN_INT (- 0x10);
730 operands[2] = GEN_INT (val + 0x10);
731 }
732 })
733
734 (define_split
735 [(set (match_operand:DI 0 "register_operand")
736 (plus:DI (match_operand:DI 1 "register_operand")
737 (match_operand:DI 2 "const_int_operand")))]
738 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
739 && GET_CODE (operands[0]) == REG
740 && M16_REG_P (REGNO (operands[0]))
741 && GET_CODE (operands[1]) == REG
742 && M16_REG_P (REGNO (operands[1]))
743 && REGNO (operands[0]) != REGNO (operands[1])
744 && GET_CODE (operands[2]) == CONST_INT
745 && ((INTVAL (operands[2]) > 0x7
746 && INTVAL (operands[2]) <= 0x7 + 0xf)
747 || (INTVAL (operands[2]) < - 0x8
748 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
749 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
750 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
751 {
752 HOST_WIDE_INT val = INTVAL (operands[2]);
753
754 if (val >= 0)
755 {
756 operands[2] = GEN_INT (0x7);
757 operands[3] = GEN_INT (val - 0x7);
758 }
759 else
760 {
761 operands[2] = GEN_INT (- 0x8);
762 operands[3] = GEN_INT (val + 0x8);
763 }
764 })
765
766 (define_insn "addsi3_internal_2"
767 [(set (match_operand:DI 0 "register_operand" "=d,d")
768 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
769 (match_operand:SI 2 "arith_operand" "d,Q"))))]
770 "TARGET_64BIT && !TARGET_MIPS16"
771 "@
772 addu\t%0,%z1,%2
773 addiu\t%0,%z1,%2"
774 [(set_attr "type" "arith")
775 (set_attr "mode" "SI")])
776
777 (define_insn ""
778 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
779 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
780 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
781 "TARGET_MIPS16 && TARGET_64BIT"
782 {
783 if (REGNO (operands[0]) == REGNO (operands[1]))
784 return "addu\t%0,%2";
785 else
786 return "addu\t%0,%1,%2";
787 }
788 [(set_attr "type" "arith")
789 (set_attr "mode" "SI")
790 (set_attr_alternative "length"
791 [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
792 (const_int 4)
793 (const_int 8))
794 (if_then_else (match_operand:VOID 2 "m16_simm4_1")
795 (const_int 4)
796 (const_int 8))
797 (const_int 4)])])
798 \f
799 ;;
800 ;; ....................
801 ;;
802 ;; SUBTRACTION
803 ;;
804 ;; ....................
805 ;;
806
807 (define_insn "subdf3"
808 [(set (match_operand:DF 0 "register_operand" "=f")
809 (minus:DF (match_operand:DF 1 "register_operand" "f")
810 (match_operand:DF 2 "register_operand" "f")))]
811 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
812 "sub.d\t%0,%1,%2"
813 [(set_attr "type" "fadd")
814 (set_attr "mode" "DF")])
815
816 (define_insn "subsf3"
817 [(set (match_operand:SF 0 "register_operand" "=f")
818 (minus:SF (match_operand:SF 1 "register_operand" "f")
819 (match_operand:SF 2 "register_operand" "f")))]
820 "TARGET_HARD_FLOAT"
821 "sub.s\t%0,%1,%2"
822 [(set_attr "type" "fadd")
823 (set_attr "mode" "SF")])
824
825 (define_expand "subsi3"
826 [(set (match_operand:SI 0 "register_operand")
827 (minus:SI (match_operand:SI 1 "register_operand")
828 (match_operand:SI 2 "register_operand")))]
829 ""
830 "")
831
832 (define_insn "subsi3_internal"
833 [(set (match_operand:SI 0 "register_operand" "=d")
834 (minus:SI (match_operand:SI 1 "register_operand" "d")
835 (match_operand:SI 2 "register_operand" "d")))]
836 ""
837 "subu\t%0,%z1,%2"
838 [(set_attr "type" "arith")
839 (set_attr "mode" "SI")])
840
841 (define_insn "subdi3"
842 [(set (match_operand:DI 0 "register_operand" "=d")
843 (minus:DI (match_operand:DI 1 "register_operand" "d")
844 (match_operand:DI 2 "register_operand" "d")))]
845 "TARGET_64BIT"
846 "dsubu\t%0,%1,%2"
847 [(set_attr "type" "arith")
848 (set_attr "mode" "DI")])
849
850 (define_insn "subsi3_internal_2"
851 [(set (match_operand:DI 0 "register_operand" "=d")
852 (sign_extend:DI
853 (minus:SI (match_operand:SI 1 "register_operand" "d")
854 (match_operand:SI 2 "register_operand" "d"))))]
855 "TARGET_64BIT"
856 "subu\t%0,%1,%2"
857 [(set_attr "type" "arith")
858 (set_attr "mode" "DI")])
859 \f
860 ;;
861 ;; ....................
862 ;;
863 ;; MULTIPLICATION
864 ;;
865 ;; ....................
866 ;;
867
868 (define_expand "muldf3"
869 [(set (match_operand:DF 0 "register_operand")
870 (mult:DF (match_operand:DF 1 "register_operand")
871 (match_operand:DF 2 "register_operand")))]
872 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
873 "")
874
875 (define_insn "muldf3_internal"
876 [(set (match_operand:DF 0 "register_operand" "=f")
877 (mult:DF (match_operand:DF 1 "register_operand" "f")
878 (match_operand:DF 2 "register_operand" "f")))]
879 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
880 "mul.d\t%0,%1,%2"
881 [(set_attr "type" "fmul")
882 (set_attr "mode" "DF")])
883
884 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
885 ;; operands may corrupt immediately following multiplies. This is a
886 ;; simple fix to insert NOPs.
887
888 (define_insn "muldf3_r4300"
889 [(set (match_operand:DF 0 "register_operand" "=f")
890 (mult:DF (match_operand:DF 1 "register_operand" "f")
891 (match_operand:DF 2 "register_operand" "f")))]
892 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
893 "mul.d\t%0,%1,%2\;nop"
894 [(set_attr "type" "fmul")
895 (set_attr "mode" "DF")
896 (set_attr "length" "8")])
897
898 (define_expand "mulsf3"
899 [(set (match_operand:SF 0 "register_operand")
900 (mult:SF (match_operand:SF 1 "register_operand")
901 (match_operand:SF 2 "register_operand")))]
902 "TARGET_HARD_FLOAT"
903 "")
904
905 (define_insn "mulsf3_internal"
906 [(set (match_operand:SF 0 "register_operand" "=f")
907 (mult:SF (match_operand:SF 1 "register_operand" "f")
908 (match_operand:SF 2 "register_operand" "f")))]
909 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
910 "mul.s\t%0,%1,%2"
911 [(set_attr "type" "fmul")
912 (set_attr "mode" "SF")])
913
914 ;; See muldf3_r4300.
915
916 (define_insn "mulsf3_r4300"
917 [(set (match_operand:SF 0 "register_operand" "=f")
918 (mult:SF (match_operand:SF 1 "register_operand" "f")
919 (match_operand:SF 2 "register_operand" "f")))]
920 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
921 "mul.s\t%0,%1,%2\;nop"
922 [(set_attr "type" "fmul")
923 (set_attr "mode" "SF")
924 (set_attr "length" "8")])
925
926
927 ;; The original R4000 has a cpu bug. If a double-word or a variable
928 ;; shift executes while an integer multiplication is in progress, the
929 ;; shift may give an incorrect result. Avoid this by keeping the mflo
930 ;; with the mult on the R4000.
931 ;;
932 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
933 ;; (also valid for MIPS R4000MC processors):
934 ;;
935 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
936 ;; this errata description.
937 ;; The following code sequence causes the R4000 to incorrectly
938 ;; execute the Double Shift Right Arithmetic 32 (dsra32)
939 ;; instruction. If the dsra32 instruction is executed during an
940 ;; integer multiply, the dsra32 will only shift by the amount in
941 ;; specified in the instruction rather than the amount plus 32
942 ;; bits.
943 ;; instruction 1: mult rs,rt integer multiply
944 ;; instruction 2-12: dsra32 rd,rt,rs doubleword shift
945 ;; right arithmetic + 32
946 ;; Workaround: A dsra32 instruction placed after an integer
947 ;; multiply should not be one of the 11 instructions after the
948 ;; multiply instruction."
949 ;;
950 ;; and:
951 ;;
952 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
953 ;; the following description.
954 ;; All extended shifts (shift by n+32) and variable shifts (32 and
955 ;; 64-bit versions) may produce incorrect results under the
956 ;; following conditions:
957 ;; 1) An integer multiply is currently executing
958 ;; 2) These types of shift instructions are executed immediately
959 ;; following an integer divide instruction.
960 ;; Workaround:
961 ;; 1) Make sure no integer multiply is running wihen these
962 ;; instruction are executed. If this cannot be predicted at
963 ;; compile time, then insert a "mfhi" to R0 instruction
964 ;; immediately after the integer multiply instruction. This
965 ;; will cause the integer multiply to complete before the shift
966 ;; is executed.
967 ;; 2) Separate integer divide and these two classes of shift
968 ;; instructions by another instruction or a noop."
969 ;;
970 ;; These processors have PRId values of 0x00004220 and 0x00004300,
971 ;; respectively.
972
973 (define_expand "mulsi3"
974 [(set (match_operand:SI 0 "register_operand")
975 (mult:SI (match_operand:SI 1 "register_operand")
976 (match_operand:SI 2 "register_operand")))]
977 ""
978 {
979 if (GENERATE_MULT3_SI || TARGET_MAD)
980 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
981 else if (!TARGET_FIX_R4000)
982 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
983 else
984 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
985 DONE;
986 })
987
988 (define_insn "mulsi3_mult3"
989 [(set (match_operand:SI 0 "register_operand" "=d,l")
990 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
991 (match_operand:SI 2 "register_operand" "d,d")))
992 (clobber (match_scratch:SI 3 "=h,h"))
993 (clobber (match_scratch:SI 4 "=l,X"))]
994 "GENERATE_MULT3_SI
995 || TARGET_MAD"
996 {
997 if (which_alternative == 1)
998 return "mult\t%1,%2";
999 if (TARGET_MAD
1000 || TARGET_MIPS5400
1001 || TARGET_MIPS5500
1002 || TARGET_MIPS7000
1003 || TARGET_MIPS9000
1004 || ISA_MIPS32
1005 || ISA_MIPS32R2
1006 || ISA_MIPS64)
1007 return "mul\t%0,%1,%2";
1008 return "mult\t%0,%1,%2";
1009 }
1010 [(set_attr "type" "imul")
1011 (set_attr "mode" "SI")])
1012
1013 ;; If a register gets allocated to LO, and we spill to memory, the reload
1014 ;; will include a move from LO to a GPR. Merge it into the multiplication
1015 ;; if it can set the GPR directly.
1016 ;;
1017 ;; Operand 0: LO
1018 ;; Operand 1: GPR (1st multiplication operand)
1019 ;; Operand 2: GPR (2nd multiplication operand)
1020 ;; Operand 3: HI
1021 ;; Operand 4: GPR (destination)
1022 (define_peephole2
1023 [(parallel
1024 [(set (match_operand:SI 0 "register_operand")
1025 (mult:SI (match_operand:SI 1 "register_operand")
1026 (match_operand:SI 2 "register_operand")))
1027 (clobber (match_operand:SI 3 "register_operand"))
1028 (clobber (scratch:SI))])
1029 (set (match_operand:SI 4 "register_operand")
1030 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1031 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
1032 [(parallel
1033 [(set (match_dup 4)
1034 (mult:SI (match_dup 1)
1035 (match_dup 2)))
1036 (clobber (match_dup 3))
1037 (clobber (match_dup 0))])])
1038
1039 (define_insn "mulsi3_internal"
1040 [(set (match_operand:SI 0 "register_operand" "=l")
1041 (mult:SI (match_operand:SI 1 "register_operand" "d")
1042 (match_operand:SI 2 "register_operand" "d")))
1043 (clobber (match_scratch:SI 3 "=h"))]
1044 "!TARGET_FIX_R4000"
1045 "mult\t%1,%2"
1046 [(set_attr "type" "imul")
1047 (set_attr "mode" "SI")])
1048
1049 (define_insn "mulsi3_r4000"
1050 [(set (match_operand:SI 0 "register_operand" "=d")
1051 (mult:SI (match_operand:SI 1 "register_operand" "d")
1052 (match_operand:SI 2 "register_operand" "d")))
1053 (clobber (match_scratch:SI 3 "=h"))
1054 (clobber (match_scratch:SI 4 "=l"))]
1055 "TARGET_FIX_R4000"
1056 "mult\t%1,%2\;mflo\t%0"
1057 [(set_attr "type" "imul")
1058 (set_attr "mode" "SI")
1059 (set_attr "length" "8")])
1060
1061 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
1062 ;; of "mult; mflo". They have the same latency, but the first form gives
1063 ;; us an extra cycle to compute the operands.
1064
1065 ;; Operand 0: LO
1066 ;; Operand 1: GPR (1st multiplication operand)
1067 ;; Operand 2: GPR (2nd multiplication operand)
1068 ;; Operand 3: HI
1069 ;; Operand 4: GPR (destination)
1070 (define_peephole2
1071 [(parallel
1072 [(set (match_operand:SI 0 "register_operand")
1073 (mult:SI (match_operand:SI 1 "register_operand")
1074 (match_operand:SI 2 "register_operand")))
1075 (clobber (match_operand:SI 3 "register_operand"))])
1076 (set (match_operand:SI 4 "register_operand")
1077 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1078 "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1079 [(set (match_dup 0)
1080 (const_int 0))
1081 (parallel
1082 [(set (match_dup 0)
1083 (plus:SI (mult:SI (match_dup 1)
1084 (match_dup 2))
1085 (match_dup 0)))
1086 (set (match_dup 4)
1087 (plus:SI (mult:SI (match_dup 1)
1088 (match_dup 2))
1089 (match_dup 0)))
1090 (clobber (match_dup 3))])])
1091
1092 ;; Multiply-accumulate patterns
1093
1094 ;; For processors that can copy the output to a general register:
1095 ;;
1096 ;; The all-d alternative is needed because the combiner will find this
1097 ;; pattern and then register alloc/reload will move registers around to
1098 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1099 ;;
1100 ;; The last alternative should be made slightly less desirable, but adding
1101 ;; "?" to the constraint is too strong, and causes values to be loaded into
1102 ;; LO even when that's more costly. For now, using "*d" mostly does the
1103 ;; trick.
1104 (define_insn "*mul_acc_si"
1105 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1106 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1107 (match_operand:SI 2 "register_operand" "d,d,d"))
1108 (match_operand:SI 3 "register_operand" "0,l,*d")))
1109 (clobber (match_scratch:SI 4 "=h,h,h"))
1110 (clobber (match_scratch:SI 5 "=X,3,l"))
1111 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1112 "(TARGET_MIPS3900
1113 || ISA_HAS_MADD_MSUB)
1114 && !TARGET_MIPS16"
1115 {
1116 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1117 if (which_alternative == 2)
1118 return "#";
1119 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1120 return "#";
1121 return madd[which_alternative];
1122 }
1123 [(set_attr "type" "imadd,imadd,multi")
1124 (set_attr "mode" "SI")
1125 (set_attr "length" "4,4,8")])
1126
1127 ;; Split the above insn if we failed to get LO allocated.
1128 (define_split
1129 [(set (match_operand:SI 0 "register_operand")
1130 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1131 (match_operand:SI 2 "register_operand"))
1132 (match_operand:SI 3 "register_operand")))
1133 (clobber (match_scratch:SI 4))
1134 (clobber (match_scratch:SI 5))
1135 (clobber (match_scratch:SI 6))]
1136 "reload_completed && !TARGET_DEBUG_D_MODE
1137 && GP_REG_P (true_regnum (operands[0]))
1138 && GP_REG_P (true_regnum (operands[3]))"
1139 [(parallel [(set (match_dup 6)
1140 (mult:SI (match_dup 1) (match_dup 2)))
1141 (clobber (match_dup 4))
1142 (clobber (match_dup 5))])
1143 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1144 "")
1145
1146 ;; Splitter to copy result of MADD to a general register
1147 (define_split
1148 [(set (match_operand:SI 0 "register_operand")
1149 (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1150 (match_operand:SI 2 "register_operand"))
1151 (match_operand:SI 3 "register_operand")))
1152 (clobber (match_scratch:SI 4))
1153 (clobber (match_scratch:SI 5))
1154 (clobber (match_scratch:SI 6))]
1155 "reload_completed && !TARGET_DEBUG_D_MODE
1156 && GP_REG_P (true_regnum (operands[0]))
1157 && true_regnum (operands[3]) == LO_REGNUM"
1158 [(parallel [(set (match_dup 3)
1159 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1160 (match_dup 3)))
1161 (clobber (match_dup 4))
1162 (clobber (match_dup 5))
1163 (clobber (match_dup 6))])
1164 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1165 "")
1166
1167 (define_insn "*macc"
1168 [(set (match_operand:SI 0 "register_operand" "=l,d")
1169 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1170 (match_operand:SI 2 "register_operand" "d,d"))
1171 (match_operand:SI 3 "register_operand" "0,l")))
1172 (clobber (match_scratch:SI 4 "=h,h"))
1173 (clobber (match_scratch:SI 5 "=X,3"))]
1174 "ISA_HAS_MACC"
1175 {
1176 if (which_alternative == 1)
1177 return "macc\t%0,%1,%2";
1178 else if (TARGET_MIPS5500)
1179 return "madd\t%1,%2";
1180 else
1181 /* The VR4130 assumes that there is a two-cycle latency between a macc
1182 that "writes" to $0 and an instruction that reads from it. We avoid
1183 this by assigning to $1 instead. */
1184 return "%[macc\t%@,%1,%2%]";
1185 }
1186 [(set_attr "type" "imadd")
1187 (set_attr "mode" "SI")])
1188
1189 (define_insn "*msac"
1190 [(set (match_operand:SI 0 "register_operand" "=l,d")
1191 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1192 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1193 (match_operand:SI 3 "register_operand" "d,d"))))
1194 (clobber (match_scratch:SI 4 "=h,h"))
1195 (clobber (match_scratch:SI 5 "=X,1"))]
1196 "ISA_HAS_MSAC"
1197 {
1198 if (which_alternative == 1)
1199 return "msac\t%0,%2,%3";
1200 else if (TARGET_MIPS5500)
1201 return "msub\t%2,%3";
1202 else
1203 return "msac\t$0,%2,%3";
1204 }
1205 [(set_attr "type" "imadd")
1206 (set_attr "mode" "SI")])
1207
1208 ;; An msac-like instruction implemented using negation and a macc.
1209 (define_insn_and_split "*msac_using_macc"
1210 [(set (match_operand:SI 0 "register_operand" "=l,d")
1211 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1212 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1213 (match_operand:SI 3 "register_operand" "d,d"))))
1214 (clobber (match_scratch:SI 4 "=h,h"))
1215 (clobber (match_scratch:SI 5 "=X,1"))
1216 (clobber (match_scratch:SI 6 "=d,d"))]
1217 "ISA_HAS_MACC && !ISA_HAS_MSAC"
1218 "#"
1219 "&& reload_completed"
1220 [(set (match_dup 6)
1221 (neg:SI (match_dup 3)))
1222 (parallel
1223 [(set (match_dup 0)
1224 (plus:SI (mult:SI (match_dup 2)
1225 (match_dup 6))
1226 (match_dup 1)))
1227 (clobber (match_dup 4))
1228 (clobber (match_dup 5))])]
1229 ""
1230 [(set_attr "type" "imadd")
1231 (set_attr "length" "8")])
1232
1233 ;; Patterns generated by the define_peephole2 below.
1234
1235 (define_insn "*macc2"
1236 [(set (match_operand:SI 0 "register_operand" "=l")
1237 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1238 (match_operand:SI 2 "register_operand" "d"))
1239 (match_dup 0)))
1240 (set (match_operand:SI 3 "register_operand" "=d")
1241 (plus:SI (mult:SI (match_dup 1)
1242 (match_dup 2))
1243 (match_dup 0)))
1244 (clobber (match_scratch:SI 4 "=h"))]
1245 "ISA_HAS_MACC && reload_completed"
1246 "macc\t%3,%1,%2"
1247 [(set_attr "type" "imadd")
1248 (set_attr "mode" "SI")])
1249
1250 (define_insn "*msac2"
1251 [(set (match_operand:SI 0 "register_operand" "=l")
1252 (minus:SI (match_dup 0)
1253 (mult:SI (match_operand:SI 1 "register_operand" "d")
1254 (match_operand:SI 2 "register_operand" "d"))))
1255 (set (match_operand:SI 3 "register_operand" "=d")
1256 (minus:SI (match_dup 0)
1257 (mult:SI (match_dup 1)
1258 (match_dup 2))))
1259 (clobber (match_scratch:SI 4 "=h"))]
1260 "ISA_HAS_MSAC && reload_completed"
1261 "msac\t%3,%1,%2"
1262 [(set_attr "type" "imadd")
1263 (set_attr "mode" "SI")])
1264
1265 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1266 ;; Similarly msac.
1267 ;;
1268 ;; Operand 0: LO
1269 ;; Operand 1: macc/msac
1270 ;; Operand 2: HI
1271 ;; Operand 3: GPR (destination)
1272 (define_peephole2
1273 [(parallel
1274 [(set (match_operand:SI 0 "register_operand")
1275 (match_operand:SI 1 "macc_msac_operand"))
1276 (clobber (match_operand:SI 2 "register_operand"))
1277 (clobber (scratch:SI))])
1278 (set (match_operand:SI 3 "register_operand")
1279 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1280 ""
1281 [(parallel [(set (match_dup 0)
1282 (match_dup 1))
1283 (set (match_dup 3)
1284 (match_dup 1))
1285 (clobber (match_dup 2))])]
1286 "")
1287
1288 ;; When we have a three-address multiplication instruction, it should
1289 ;; be faster to do a separate multiply and add, rather than moving
1290 ;; something into LO in order to use a macc instruction.
1291 ;;
1292 ;; This peephole needs a scratch register to cater for the case when one
1293 ;; of the multiplication operands is the same as the destination.
1294 ;;
1295 ;; Operand 0: GPR (scratch)
1296 ;; Operand 1: LO
1297 ;; Operand 2: GPR (addend)
1298 ;; Operand 3: GPR (destination)
1299 ;; Operand 4: macc/msac
1300 ;; Operand 5: HI
1301 ;; Operand 6: new multiplication
1302 ;; Operand 7: new addition/subtraction
1303 (define_peephole2
1304 [(match_scratch:SI 0 "d")
1305 (set (match_operand:SI 1 "register_operand")
1306 (match_operand:SI 2 "register_operand"))
1307 (match_dup 0)
1308 (parallel
1309 [(set (match_operand:SI 3 "register_operand")
1310 (match_operand:SI 4 "macc_msac_operand"))
1311 (clobber (match_operand:SI 5 "register_operand"))
1312 (clobber (match_dup 1))])]
1313 "GENERATE_MULT3_SI
1314 && true_regnum (operands[1]) == LO_REGNUM
1315 && peep2_reg_dead_p (2, operands[1])
1316 && GP_REG_P (true_regnum (operands[3]))"
1317 [(parallel [(set (match_dup 0)
1318 (match_dup 6))
1319 (clobber (match_dup 5))
1320 (clobber (match_dup 1))])
1321 (set (match_dup 3)
1322 (match_dup 7))]
1323 {
1324 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1325 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1326 operands[2], operands[0]);
1327 })
1328
1329 ;; Same as above, except LO is the initial target of the macc.
1330 ;;
1331 ;; Operand 0: GPR (scratch)
1332 ;; Operand 1: LO
1333 ;; Operand 2: GPR (addend)
1334 ;; Operand 3: macc/msac
1335 ;; Operand 4: HI
1336 ;; Operand 5: GPR (destination)
1337 ;; Operand 6: new multiplication
1338 ;; Operand 7: new addition/subtraction
1339 (define_peephole2
1340 [(match_scratch:SI 0 "d")
1341 (set (match_operand:SI 1 "register_operand")
1342 (match_operand:SI 2 "register_operand"))
1343 (match_dup 0)
1344 (parallel
1345 [(set (match_dup 1)
1346 (match_operand:SI 3 "macc_msac_operand"))
1347 (clobber (match_operand:SI 4 "register_operand"))
1348 (clobber (scratch:SI))])
1349 (match_dup 0)
1350 (set (match_operand:SI 5 "register_operand")
1351 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1352 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1353 [(parallel [(set (match_dup 0)
1354 (match_dup 6))
1355 (clobber (match_dup 4))
1356 (clobber (match_dup 1))])
1357 (set (match_dup 5)
1358 (match_dup 7))]
1359 {
1360 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1361 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1362 operands[2], operands[0]);
1363 })
1364
1365 (define_insn "*mul_sub_si"
1366 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1367 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1368 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1369 (match_operand:SI 3 "register_operand" "d,d,d"))))
1370 (clobber (match_scratch:SI 4 "=h,h,h"))
1371 (clobber (match_scratch:SI 5 "=X,1,l"))
1372 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1373 "ISA_HAS_MADD_MSUB"
1374 "@
1375 msub\t%2,%3
1376 #
1377 #"
1378 [(set_attr "type" "imadd,multi,multi")
1379 (set_attr "mode" "SI")
1380 (set_attr "length" "4,8,8")])
1381
1382 ;; Split the above insn if we failed to get LO allocated.
1383 (define_split
1384 [(set (match_operand:SI 0 "register_operand")
1385 (minus:SI (match_operand:SI 1 "register_operand")
1386 (mult:SI (match_operand:SI 2 "register_operand")
1387 (match_operand:SI 3 "register_operand"))))
1388 (clobber (match_scratch:SI 4))
1389 (clobber (match_scratch:SI 5))
1390 (clobber (match_scratch:SI 6))]
1391 "reload_completed && !TARGET_DEBUG_D_MODE
1392 && GP_REG_P (true_regnum (operands[0]))
1393 && GP_REG_P (true_regnum (operands[1]))"
1394 [(parallel [(set (match_dup 6)
1395 (mult:SI (match_dup 2) (match_dup 3)))
1396 (clobber (match_dup 4))
1397 (clobber (match_dup 5))])
1398 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1399 "")
1400
1401 ;; Splitter to copy result of MSUB to a general register
1402 (define_split
1403 [(set (match_operand:SI 0 "register_operand")
1404 (minus:SI (match_operand:SI 1 "register_operand")
1405 (mult:SI (match_operand:SI 2 "register_operand")
1406 (match_operand:SI 3 "register_operand"))))
1407 (clobber (match_scratch:SI 4))
1408 (clobber (match_scratch:SI 5))
1409 (clobber (match_scratch:SI 6))]
1410 "reload_completed && !TARGET_DEBUG_D_MODE
1411 && GP_REG_P (true_regnum (operands[0]))
1412 && true_regnum (operands[1]) == LO_REGNUM"
1413 [(parallel [(set (match_dup 1)
1414 (minus:SI (match_dup 1)
1415 (mult:SI (match_dup 2) (match_dup 3))))
1416 (clobber (match_dup 4))
1417 (clobber (match_dup 5))
1418 (clobber (match_dup 6))])
1419 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1420 "")
1421
1422 (define_insn "*muls"
1423 [(set (match_operand:SI 0 "register_operand" "=l,d")
1424 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1425 (match_operand:SI 2 "register_operand" "d,d"))))
1426 (clobber (match_scratch:SI 3 "=h,h"))
1427 (clobber (match_scratch:SI 4 "=X,l"))]
1428 "ISA_HAS_MULS"
1429 "@
1430 muls\t$0,%1,%2
1431 muls\t%0,%1,%2"
1432 [(set_attr "type" "imul")
1433 (set_attr "mode" "SI")])
1434
1435 (define_expand "muldi3"
1436 [(set (match_operand:DI 0 "register_operand")
1437 (mult:DI (match_operand:DI 1 "register_operand")
1438 (match_operand:DI 2 "register_operand")))]
1439 "TARGET_64BIT"
1440 {
1441 if (GENERATE_MULT3_DI)
1442 emit_insn (gen_muldi3_mult3 (operands[0], operands[1], operands[2]));
1443 else if (!TARGET_FIX_R4000)
1444 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1445 else
1446 emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1447 DONE;
1448 })
1449
1450 (define_insn "muldi3_mult3"
1451 [(set (match_operand:DI 0 "register_operand" "=d")
1452 (mult:DI (match_operand:DI 1 "register_operand" "d")
1453 (match_operand:DI 2 "register_operand" "d")))
1454 (clobber (match_scratch:DI 3 "=h"))
1455 (clobber (match_scratch:DI 4 "=l"))]
1456 "TARGET_64BIT && GENERATE_MULT3_DI"
1457 "dmult\t%0,%1,%2"
1458 [(set_attr "type" "imul")
1459 (set_attr "mode" "DI")])
1460
1461 (define_insn "muldi3_internal"
1462 [(set (match_operand:DI 0 "register_operand" "=l")
1463 (mult:DI (match_operand:DI 1 "register_operand" "d")
1464 (match_operand:DI 2 "register_operand" "d")))
1465 (clobber (match_scratch:DI 3 "=h"))]
1466 "TARGET_64BIT && !TARGET_FIX_R4000"
1467 "dmult\t%1,%2"
1468 [(set_attr "type" "imul")
1469 (set_attr "mode" "DI")])
1470
1471 (define_insn "muldi3_r4000"
1472 [(set (match_operand:DI 0 "register_operand" "=d")
1473 (mult:DI (match_operand:DI 1 "register_operand" "d")
1474 (match_operand:DI 2 "register_operand" "d")))
1475 (clobber (match_scratch:DI 3 "=h"))
1476 (clobber (match_scratch:DI 4 "=l"))]
1477 "TARGET_64BIT && TARGET_FIX_R4000"
1478 "dmult\t%1,%2\;mflo\t%0"
1479 [(set_attr "type" "imul")
1480 (set_attr "mode" "DI")
1481 (set_attr "length" "8")])
1482
1483 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1484
1485 (define_expand "mulsidi3"
1486 [(parallel
1487 [(set (match_operand:DI 0 "register_operand")
1488 (mult:DI
1489 (sign_extend:DI (match_operand:SI 1 "register_operand"))
1490 (sign_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_mulsidi3_32bit_internal (operands[0], operands[1],
1500 operands[2]));
1501 else
1502 emit_insn (gen_mulsidi3_32bit_r4000 (operands[0], operands[1],
1503 operands[2]));
1504 DONE;
1505 }
1506 })
1507
1508 (define_insn "mulsidi3_32bit_internal"
1509 [(set (match_operand:DI 0 "register_operand" "=x")
1510 (mult:DI
1511 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1512 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1513 "!TARGET_64BIT && !TARGET_FIX_R4000"
1514 "mult\t%1,%2"
1515 [(set_attr "type" "imul")
1516 (set_attr "mode" "SI")])
1517
1518 (define_insn "mulsidi3_32bit_r4000"
1519 [(set (match_operand:DI 0 "register_operand" "=d")
1520 (mult:DI
1521 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1522 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1523 (clobber (match_scratch:DI 3 "=l"))
1524 (clobber (match_scratch:DI 4 "=h"))]
1525 "!TARGET_64BIT && TARGET_FIX_R4000"
1526 "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1527 [(set_attr "type" "imul")
1528 (set_attr "mode" "SI")
1529 (set_attr "length" "12")])
1530
1531 (define_insn_and_split "*mulsidi3_64bit"
1532 [(set (match_operand:DI 0 "register_operand" "=d")
1533 (mult:DI (match_operator:DI 1 "extend_operator"
1534 [(match_operand:SI 3 "register_operand" "d")])
1535 (match_operator:DI 2 "extend_operator"
1536 [(match_operand:SI 4 "register_operand" "d")])))
1537 (clobber (match_scratch:DI 5 "=l"))
1538 (clobber (match_scratch:DI 6 "=h"))
1539 (clobber (match_scratch:DI 7 "=d"))]
1540 "TARGET_64BIT && !TARGET_FIX_R4000
1541 && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1542 "#"
1543 "&& reload_completed"
1544 [(parallel
1545 [(set (match_dup 5)
1546 (sign_extend:DI
1547 (mult:SI (match_dup 3)
1548 (match_dup 4))))
1549 (set (match_dup 6)
1550 (ashiftrt:DI
1551 (mult:DI (match_dup 1)
1552 (match_dup 2))
1553 (const_int 32)))])
1554
1555 ;; OP7 <- LO, OP0 <- HI
1556 (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
1557 (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
1558
1559 ;; Zero-extend OP7.
1560 (set (match_dup 7)
1561 (ashift:DI (match_dup 7)
1562 (const_int 32)))
1563 (set (match_dup 7)
1564 (lshiftrt:DI (match_dup 7)
1565 (const_int 32)))
1566
1567 ;; Shift OP0 into place.
1568 (set (match_dup 0)
1569 (ashift:DI (match_dup 0)
1570 (const_int 32)))
1571
1572 ;; OR the two halves together
1573 (set (match_dup 0)
1574 (ior:DI (match_dup 0)
1575 (match_dup 7)))]
1576 ""
1577 [(set_attr "type" "imul")
1578 (set_attr "mode" "SI")
1579 (set_attr "length" "24")])
1580
1581 (define_insn "*mulsidi3_64bit_parts"
1582 [(set (match_operand:DI 0 "register_operand" "=l")
1583 (sign_extend:DI
1584 (mult:SI (match_operand:SI 2 "register_operand" "d")
1585 (match_operand:SI 3 "register_operand" "d"))))
1586 (set (match_operand:DI 1 "register_operand" "=h")
1587 (ashiftrt:DI
1588 (mult:DI
1589 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1590 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1591 (const_int 32)))]
1592 "TARGET_64BIT && !TARGET_FIX_R4000
1593 && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1594 {
1595 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1596 return "mult\t%2,%3";
1597 else
1598 return "multu\t%2,%3";
1599 }
1600 [(set_attr "type" "imul")
1601 (set_attr "mode" "SI")])
1602
1603 (define_expand "umulsidi3"
1604 [(parallel
1605 [(set (match_operand:DI 0 "register_operand")
1606 (mult:DI
1607 (zero_extend:DI (match_operand:SI 1 "register_operand"))
1608 (zero_extend:DI (match_operand:SI 2 "register_operand"))))
1609 (clobber (scratch:DI))
1610 (clobber (scratch:DI))
1611 (clobber (scratch:DI))])]
1612 "!TARGET_64BIT || !TARGET_FIX_R4000"
1613 {
1614 if (!TARGET_64BIT)
1615 {
1616 if (!TARGET_FIX_R4000)
1617 emit_insn (gen_umulsidi3_32bit_internal (operands[0], operands[1],
1618 operands[2]));
1619 else
1620 emit_insn (gen_umulsidi3_32bit_r4000 (operands[0], operands[1],
1621 operands[2]));
1622 DONE;
1623 }
1624 })
1625
1626 (define_insn "umulsidi3_32bit_internal"
1627 [(set (match_operand:DI 0 "register_operand" "=x")
1628 (mult:DI
1629 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1630 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1631 "!TARGET_64BIT && !TARGET_FIX_R4000"
1632 "multu\t%1,%2"
1633 [(set_attr "type" "imul")
1634 (set_attr "mode" "SI")])
1635
1636 (define_insn "umulsidi3_32bit_r4000"
1637 [(set (match_operand:DI 0 "register_operand" "=d")
1638 (mult:DI
1639 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1640 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1641 (clobber (match_scratch:DI 3 "=l"))
1642 (clobber (match_scratch:DI 4 "=h"))]
1643 "!TARGET_64BIT && TARGET_FIX_R4000"
1644 "multu\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1645 [(set_attr "type" "imul")
1646 (set_attr "mode" "SI")
1647 (set_attr "length" "12")])
1648
1649 ;; Widening multiply with negation.
1650 (define_insn "*muls_di"
1651 [(set (match_operand:DI 0 "register_operand" "=x")
1652 (neg:DI
1653 (mult:DI
1654 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1655 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1656 "!TARGET_64BIT && ISA_HAS_MULS"
1657 "muls\t$0,%1,%2"
1658 [(set_attr "type" "imul")
1659 (set_attr "length" "4")
1660 (set_attr "mode" "SI")])
1661
1662 (define_insn "*umuls_di"
1663 [(set (match_operand:DI 0 "register_operand" "=x")
1664 (neg:DI
1665 (mult:DI
1666 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1667 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1668 "!TARGET_64BIT && ISA_HAS_MULS"
1669 "mulsu\t$0,%1,%2"
1670 [(set_attr "type" "imul")
1671 (set_attr "length" "4")
1672 (set_attr "mode" "SI")])
1673
1674 (define_insn "*smsac_di"
1675 [(set (match_operand:DI 0 "register_operand" "=x")
1676 (minus:DI
1677 (match_operand:DI 3 "register_operand" "0")
1678 (mult:DI
1679 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1680 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1681 "!TARGET_64BIT && ISA_HAS_MSAC"
1682 {
1683 if (TARGET_MIPS5500)
1684 return "msub\t%1,%2";
1685 else
1686 return "msac\t$0,%1,%2";
1687 }
1688 [(set_attr "type" "imadd")
1689 (set_attr "length" "4")
1690 (set_attr "mode" "SI")])
1691
1692 (define_insn "*umsac_di"
1693 [(set (match_operand:DI 0 "register_operand" "=x")
1694 (minus:DI
1695 (match_operand:DI 3 "register_operand" "0")
1696 (mult:DI
1697 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1698 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1699 "!TARGET_64BIT && ISA_HAS_MSAC"
1700 {
1701 if (TARGET_MIPS5500)
1702 return "msubu\t%1,%2";
1703 else
1704 return "msacu\t$0,%1,%2";
1705 }
1706 [(set_attr "type" "imadd")
1707 (set_attr "length" "4")
1708 (set_attr "mode" "SI")])
1709
1710 ;; _highpart patterns
1711 (define_expand "umulsi3_highpart"
1712 [(set (match_operand:SI 0 "register_operand")
1713 (truncate:SI
1714 (lshiftrt:DI
1715 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
1716 (zero_extend:DI (match_operand:SI 2 "register_operand")))
1717 (const_int 32))))]
1718 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1719 {
1720 if (ISA_HAS_MULHI)
1721 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
1722 operands[2]));
1723 else
1724 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
1725 operands[2]));
1726 DONE;
1727 })
1728
1729 (define_insn "umulsi3_highpart_internal"
1730 [(set (match_operand:SI 0 "register_operand" "=h")
1731 (truncate:SI
1732 (lshiftrt:DI
1733 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1734 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1735 (const_int 32))))
1736 (clobber (match_scratch:SI 3 "=l"))]
1737 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1738 "multu\t%1,%2"
1739 [(set_attr "type" "imul")
1740 (set_attr "mode" "SI")
1741 (set_attr "length" "4")])
1742
1743 (define_insn "umulsi3_highpart_mulhi_internal"
1744 [(set (match_operand:SI 0 "register_operand" "=h,d")
1745 (truncate:SI
1746 (lshiftrt:DI
1747 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1748 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1749 (const_int 32))))
1750 (clobber (match_scratch:SI 3 "=l,l"))
1751 (clobber (match_scratch:SI 4 "=X,h"))]
1752 "ISA_HAS_MULHI"
1753 "@
1754 multu\t%1,%2
1755 mulhiu\t%0,%1,%2"
1756 [(set_attr "type" "imul")
1757 (set_attr "mode" "SI")
1758 (set_attr "length" "4")])
1759
1760 (define_insn "umulsi3_highpart_neg_mulhi_internal"
1761 [(set (match_operand:SI 0 "register_operand" "=h,d")
1762 (truncate:SI
1763 (lshiftrt:DI
1764 (neg:DI
1765 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1766 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1767 (const_int 32))))
1768 (clobber (match_scratch:SI 3 "=l,l"))
1769 (clobber (match_scratch:SI 4 "=X,h"))]
1770 "ISA_HAS_MULHI"
1771 "@
1772 mulshiu\t%.,%1,%2
1773 mulshiu\t%0,%1,%2"
1774 [(set_attr "type" "imul")
1775 (set_attr "mode" "SI")
1776 (set_attr "length" "4")])
1777
1778 (define_expand "smulsi3_highpart"
1779 [(set (match_operand:SI 0 "register_operand")
1780 (truncate:SI
1781 (lshiftrt:DI
1782 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
1783 (sign_extend:DI (match_operand:SI 2 "register_operand")))
1784 (const_int 32))))]
1785 "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1786 {
1787 if (ISA_HAS_MULHI)
1788 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
1789 operands[2]));
1790 else
1791 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
1792 operands[2]));
1793 DONE;
1794 })
1795
1796 (define_insn "smulsi3_highpart_internal"
1797 [(set (match_operand:SI 0 "register_operand" "=h")
1798 (truncate:SI
1799 (lshiftrt:DI
1800 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1801 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1802 (const_int 32))))
1803 (clobber (match_scratch:SI 3 "=l"))]
1804 "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1805 "mult\t%1,%2"
1806 [(set_attr "type" "imul")
1807 (set_attr "mode" "SI")
1808 (set_attr "length" "4")])
1809
1810 (define_insn "smulsi3_highpart_mulhi_internal"
1811 [(set (match_operand:SI 0 "register_operand" "=h,d")
1812 (truncate:SI
1813 (lshiftrt:DI
1814 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1815 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1816 (const_int 32))))
1817 (clobber (match_scratch:SI 3 "=l,l"))
1818 (clobber (match_scratch:SI 4 "=X,h"))]
1819 "ISA_HAS_MULHI"
1820 "@
1821 mult\t%1,%2
1822 mulhi\t%0,%1,%2"
1823 [(set_attr "type" "imul")
1824 (set_attr "mode" "SI")
1825 (set_attr "length" "4")])
1826
1827 (define_insn "smulsi3_highpart_neg_mulhi_internal"
1828 [(set (match_operand:SI 0 "register_operand" "=h,d")
1829 (truncate:SI
1830 (lshiftrt:DI
1831 (neg:DI
1832 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1833 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1834 (const_int 32))))
1835 (clobber (match_scratch:SI 3 "=l,l"))
1836 (clobber (match_scratch:SI 4 "=X,h"))]
1837 "ISA_HAS_MULHI"
1838 "@
1839 mulshi\t%.,%1,%2
1840 mulshi\t%0,%1,%2"
1841 [(set_attr "type" "imul")
1842 (set_attr "mode" "SI")])
1843
1844 (define_insn "smuldi3_highpart"
1845 [(set (match_operand:DI 0 "register_operand" "=h")
1846 (truncate:DI
1847 (lshiftrt:TI
1848 (mult:TI
1849 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
1850 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
1851 (const_int 64))))
1852 (clobber (match_scratch:DI 3 "=l"))]
1853 "TARGET_64BIT && !TARGET_FIX_R4000"
1854 "dmult\t%1,%2"
1855 [(set_attr "type" "imul")
1856 (set_attr "mode" "DI")])
1857
1858 ;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
1859 ;; which says that dmultu does not always produce the correct result.
1860 (define_insn "umuldi3_highpart"
1861 [(set (match_operand:DI 0 "register_operand" "=h")
1862 (truncate:DI
1863 (lshiftrt:TI
1864 (mult:TI
1865 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
1866 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
1867 (const_int 64))))
1868 (clobber (match_scratch:DI 3 "=l"))]
1869 "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
1870 "dmultu\t%1,%2"
1871 [(set_attr "type" "imul")
1872 (set_attr "mode" "DI")])
1873
1874
1875 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1876 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1877
1878 (define_insn "madsi"
1879 [(set (match_operand:SI 0 "register_operand" "+l")
1880 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1881 (match_operand:SI 2 "register_operand" "d"))
1882 (match_dup 0)))
1883 (clobber (match_scratch:SI 3 "=h"))]
1884 "TARGET_MAD"
1885 "mad\t%1,%2"
1886 [(set_attr "type" "imadd")
1887 (set_attr "mode" "SI")])
1888
1889 (define_insn "*umul_acc_di"
1890 [(set (match_operand:DI 0 "register_operand" "=x")
1891 (plus:DI
1892 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1893 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1894 (match_operand:DI 3 "register_operand" "0")))]
1895 "(TARGET_MAD || ISA_HAS_MACC)
1896 && !TARGET_64BIT"
1897 {
1898 if (TARGET_MAD)
1899 return "madu\t%1,%2";
1900 else if (TARGET_MIPS5500)
1901 return "maddu\t%1,%2";
1902 else
1903 /* See comment in *macc. */
1904 return "%[maccu\t%@,%1,%2%]";
1905 }
1906 [(set_attr "type" "imadd")
1907 (set_attr "mode" "SI")])
1908
1909
1910 (define_insn "*smul_acc_di"
1911 [(set (match_operand:DI 0 "register_operand" "=x")
1912 (plus:DI
1913 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1914 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1915 (match_operand:DI 3 "register_operand" "0")))]
1916 "(TARGET_MAD || ISA_HAS_MACC)
1917 && !TARGET_64BIT"
1918 {
1919 if (TARGET_MAD)
1920 return "mad\t%1,%2";
1921 else if (TARGET_MIPS5500)
1922 return "madd\t%1,%2";
1923 else
1924 /* See comment in *macc. */
1925 return "%[macc\t%@,%1,%2%]";
1926 }
1927 [(set_attr "type" "imadd")
1928 (set_attr "mode" "SI")])
1929
1930 ;; Floating point multiply accumulate instructions.
1931
1932 (define_insn ""
1933 [(set (match_operand:DF 0 "register_operand" "=f")
1934 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1935 (match_operand:DF 2 "register_operand" "f"))
1936 (match_operand:DF 3 "register_operand" "f")))]
1937 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1938 "madd.d\t%0,%3,%1,%2"
1939 [(set_attr "type" "fmadd")
1940 (set_attr "mode" "DF")])
1941
1942 (define_insn ""
1943 [(set (match_operand:SF 0 "register_operand" "=f")
1944 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1945 (match_operand:SF 2 "register_operand" "f"))
1946 (match_operand:SF 3 "register_operand" "f")))]
1947 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1948 "madd.s\t%0,%3,%1,%2"
1949 [(set_attr "type" "fmadd")
1950 (set_attr "mode" "SF")])
1951
1952 (define_insn ""
1953 [(set (match_operand:DF 0 "register_operand" "=f")
1954 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1955 (match_operand:DF 2 "register_operand" "f"))
1956 (match_operand:DF 3 "register_operand" "f")))]
1957 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1958 "msub.d\t%0,%3,%1,%2"
1959 [(set_attr "type" "fmadd")
1960 (set_attr "mode" "DF")])
1961
1962 (define_insn ""
1963 [(set (match_operand:SF 0 "register_operand" "=f")
1964 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1965 (match_operand:SF 2 "register_operand" "f"))
1966 (match_operand:SF 3 "register_operand" "f")))]
1967
1968 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1969 "msub.s\t%0,%3,%1,%2"
1970 [(set_attr "type" "fmadd")
1971 (set_attr "mode" "SF")])
1972
1973 (define_insn ""
1974 [(set (match_operand:DF 0 "register_operand" "=f")
1975 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1976 (match_operand:DF 2 "register_operand" "f"))
1977 (match_operand:DF 3 "register_operand" "f"))))]
1978 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1979 "nmadd.d\t%0,%3,%1,%2"
1980 [(set_attr "type" "fmadd")
1981 (set_attr "mode" "DF")])
1982
1983 (define_insn ""
1984 [(set (match_operand:SF 0 "register_operand" "=f")
1985 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1986 (match_operand:SF 2 "register_operand" "f"))
1987 (match_operand:SF 3 "register_operand" "f"))))]
1988 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
1989 "nmadd.s\t%0,%3,%1,%2"
1990 [(set_attr "type" "fmadd")
1991 (set_attr "mode" "SF")])
1992
1993 (define_insn ""
1994 [(set (match_operand:DF 0 "register_operand" "=f")
1995 (minus:DF (match_operand:DF 1 "register_operand" "f")
1996 (mult:DF (match_operand:DF 2 "register_operand" "f")
1997 (match_operand:DF 3 "register_operand" "f"))))]
1998 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
1999 "nmsub.d\t%0,%1,%2,%3"
2000 [(set_attr "type" "fmadd")
2001 (set_attr "mode" "DF")])
2002
2003 (define_insn ""
2004 [(set (match_operand:SF 0 "register_operand" "=f")
2005 (minus:SF (match_operand:SF 1 "register_operand" "f")
2006 (mult:SF (match_operand:SF 2 "register_operand" "f")
2007 (match_operand:SF 3 "register_operand" "f"))))]
2008 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2009 "nmsub.s\t%0,%1,%2,%3"
2010 [(set_attr "type" "fmadd")
2011 (set_attr "mode" "SF")])
2012 \f
2013 ;;
2014 ;; ....................
2015 ;;
2016 ;; DIVISION and REMAINDER
2017 ;;
2018 ;; ....................
2019 ;;
2020
2021 (define_expand "divdf3"
2022 [(set (match_operand:DF 0 "register_operand")
2023 (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
2024 (match_operand:DF 2 "register_operand")))]
2025 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2026 {
2027 if (const_float_1_operand (operands[1], DFmode))
2028 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2029 operands[1] = force_reg (DFmode, operands[1]);
2030 })
2031
2032 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2033 ;;
2034 ;; If an mfc1 or dmfc1 happens to access the floating point register
2035 ;; file at the same time a long latency operation (div, sqrt, recip,
2036 ;; sqrt) iterates an intermediate result back through the floating
2037 ;; point register file bypass, then instead returning the correct
2038 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2039 ;; result of the long latency operation.
2040 ;;
2041 ;; The workaround is to insert an unconditional 'mov' from/to the
2042 ;; long latency op destination register.
2043
2044 (define_insn "*divdf3"
2045 [(set (match_operand:DF 0 "register_operand" "=f")
2046 (div:DF (match_operand:DF 1 "register_operand" "f")
2047 (match_operand:DF 2 "register_operand" "f")))]
2048 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2049 {
2050 if (TARGET_FIX_SB1)
2051 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2052 else
2053 return "div.d\t%0,%1,%2";
2054 }
2055 [(set_attr "type" "fdiv")
2056 (set_attr "mode" "DF")
2057 (set (attr "length")
2058 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2059 (const_int 8)
2060 (const_int 4)))])
2061
2062
2063 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2064 ;;
2065 ;; In certain cases, div.s and div.ps may have a rounding error
2066 ;; and/or wrong inexact flag.
2067 ;;
2068 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2069 ;; errata, or if working around those errata and a slight loss of
2070 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2071 (define_expand "divsf3"
2072 [(set (match_operand:SF 0 "register_operand")
2073 (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
2074 (match_operand:SF 2 "register_operand")))]
2075 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2076 {
2077 if (const_float_1_operand (operands[1], SFmode))
2078 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2079 operands[1] = force_reg (SFmode, operands[1]);
2080 })
2081
2082 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2083 ;; "divdf3" comment for details).
2084 ;;
2085 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2086 ;; "divsf3" comment for details).
2087 (define_insn "*divsf3"
2088 [(set (match_operand:SF 0 "register_operand" "=f")
2089 (div:SF (match_operand:SF 1 "register_operand" "f")
2090 (match_operand:SF 2 "register_operand" "f")))]
2091 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2092 {
2093 if (TARGET_FIX_SB1)
2094 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2095 else
2096 return "div.s\t%0,%1,%2";
2097 }
2098 [(set_attr "type" "fdiv")
2099 (set_attr "mode" "SF")
2100 (set (attr "length")
2101 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2102 (const_int 8)
2103 (const_int 4)))])
2104
2105 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2106 ;; "divdf3" comment for details).
2107 (define_insn ""
2108 [(set (match_operand:DF 0 "register_operand" "=f")
2109 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2110 (match_operand:DF 2 "register_operand" "f")))]
2111 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2112 {
2113 if (TARGET_FIX_SB1)
2114 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2115 else
2116 return "recip.d\t%0,%2";
2117 }
2118 [(set_attr "type" "fdiv")
2119 (set_attr "mode" "DF")
2120 (set (attr "length")
2121 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2122 (const_int 8)
2123 (const_int 4)))])
2124
2125 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2126 ;; "divdf3" comment for details).
2127 (define_insn ""
2128 [(set (match_operand:SF 0 "register_operand" "=f")
2129 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2130 (match_operand:SF 2 "register_operand" "f")))]
2131 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2132 {
2133 if (TARGET_FIX_SB1)
2134 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2135 else
2136 return "recip.s\t%0,%2";
2137 }
2138 [(set_attr "type" "fdiv")
2139 (set_attr "mode" "SF")
2140 (set (attr "length")
2141 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2142 (const_int 8)
2143 (const_int 4)))])
2144
2145 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
2146 ;; with negative operands. We use special libgcc functions instead.
2147 (define_insn "divmodsi4"
2148 [(set (match_operand:SI 0 "register_operand" "=l")
2149 (div:SI (match_operand:SI 1 "register_operand" "d")
2150 (match_operand:SI 2 "register_operand" "d")))
2151 (set (match_operand:SI 3 "register_operand" "=h")
2152 (mod:SI (match_dup 1)
2153 (match_dup 2)))]
2154 "!TARGET_FIX_VR4120"
2155 { return mips_output_division ("div\t$0,%1,%2", operands); }
2156 [(set_attr "type" "idiv")
2157 (set_attr "mode" "SI")])
2158
2159 (define_insn "divmoddi4"
2160 [(set (match_operand:DI 0 "register_operand" "=l")
2161 (div:DI (match_operand:DI 1 "register_operand" "d")
2162 (match_operand:DI 2 "register_operand" "d")))
2163 (set (match_operand:DI 3 "register_operand" "=h")
2164 (mod:DI (match_dup 1)
2165 (match_dup 2)))]
2166 "TARGET_64BIT && !TARGET_FIX_VR4120"
2167 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2168 [(set_attr "type" "idiv")
2169 (set_attr "mode" "DI")])
2170
2171 (define_insn "udivmodsi4"
2172 [(set (match_operand:SI 0 "register_operand" "=l")
2173 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2174 (match_operand:SI 2 "register_operand" "d")))
2175 (set (match_operand:SI 3 "register_operand" "=h")
2176 (umod:SI (match_dup 1)
2177 (match_dup 2)))]
2178 ""
2179 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2180 [(set_attr "type" "idiv")
2181 (set_attr "mode" "SI")])
2182
2183 (define_insn "udivmoddi4"
2184 [(set (match_operand:DI 0 "register_operand" "=l")
2185 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2186 (match_operand:DI 2 "register_operand" "d")))
2187 (set (match_operand:DI 3 "register_operand" "=h")
2188 (umod:DI (match_dup 1)
2189 (match_dup 2)))]
2190 "TARGET_64BIT"
2191 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2192 [(set_attr "type" "idiv")
2193 (set_attr "mode" "DI")])
2194 \f
2195 ;;
2196 ;; ....................
2197 ;;
2198 ;; SQUARE ROOT
2199 ;;
2200 ;; ....................
2201
2202 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2203 ;; "divdf3" comment for details).
2204 (define_insn "sqrtdf2"
2205 [(set (match_operand:DF 0 "register_operand" "=f")
2206 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2207 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2208 {
2209 if (TARGET_FIX_SB1)
2210 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2211 else
2212 return "sqrt.d\t%0,%1";
2213 }
2214 [(set_attr "type" "fsqrt")
2215 (set_attr "mode" "DF")
2216 (set (attr "length")
2217 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2218 (const_int 8)
2219 (const_int 4)))])
2220
2221 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2222 ;; "divdf3" comment for details).
2223 (define_insn "sqrtsf2"
2224 [(set (match_operand:SF 0 "register_operand" "=f")
2225 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2226 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2227 {
2228 if (TARGET_FIX_SB1)
2229 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2230 else
2231 return "sqrt.s\t%0,%1";
2232 }
2233 [(set_attr "type" "fsqrt")
2234 (set_attr "mode" "SF")
2235 (set (attr "length")
2236 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2237 (const_int 8)
2238 (const_int 4)))])
2239
2240 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2241 ;; "divdf3" comment for details).
2242 (define_insn ""
2243 [(set (match_operand:DF 0 "register_operand" "=f")
2244 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2245 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2246 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2247 {
2248 if (TARGET_FIX_SB1)
2249 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2250 else
2251 return "rsqrt.d\t%0,%2";
2252 }
2253 [(set_attr "type" "frsqrt")
2254 (set_attr "mode" "DF")
2255 (set (attr "length")
2256 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2257 (const_int 8)
2258 (const_int 4)))])
2259
2260 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2261 ;; "divdf3" comment for details).
2262 (define_insn ""
2263 [(set (match_operand:SF 0 "register_operand" "=f")
2264 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2265 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2266 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2267 {
2268 if (TARGET_FIX_SB1)
2269 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2270 else
2271 return "rsqrt.s\t%0,%2";
2272 }
2273 [(set_attr "type" "frsqrt")
2274 (set_attr "mode" "SF")
2275 (set (attr "length")
2276 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2277 (const_int 8)
2278 (const_int 4)))])
2279 \f
2280 ;;
2281 ;; ....................
2282 ;;
2283 ;; ABSOLUTE VALUE
2284 ;;
2285 ;; ....................
2286
2287 ;; Do not use the integer abs macro instruction, since that signals an
2288 ;; exception on -2147483648 (sigh).
2289
2290 (define_insn "abssi2"
2291 [(set (match_operand:SI 0 "register_operand" "=d")
2292 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2293 "!TARGET_MIPS16"
2294 {
2295 operands[2] = const0_rtx;
2296
2297 if (REGNO (operands[0]) == REGNO (operands[1]))
2298 {
2299 if (GENERATE_BRANCHLIKELY)
2300 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2301 else
2302 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2303 }
2304 else
2305 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2306 }
2307 [(set_attr "type" "multi")
2308 (set_attr "mode" "SI")
2309 (set_attr "length" "12")])
2310
2311 (define_insn "absdi2"
2312 [(set (match_operand:DI 0 "register_operand" "=d")
2313 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2314 "TARGET_64BIT && !TARGET_MIPS16"
2315 {
2316 unsigned int regno1;
2317 operands[2] = const0_rtx;
2318
2319 if (GET_CODE (operands[1]) == REG)
2320 regno1 = REGNO (operands[1]);
2321 else
2322 regno1 = REGNO (XEXP (operands[1], 0));
2323
2324 if (REGNO (operands[0]) == regno1)
2325 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2326 else
2327 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2328 }
2329 [(set_attr "type" "multi")
2330 (set_attr "mode" "DI")
2331 (set_attr "length" "12")])
2332
2333 (define_insn "absdf2"
2334 [(set (match_operand:DF 0 "register_operand" "=f")
2335 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2336 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2337 "abs.d\t%0,%1"
2338 [(set_attr "type" "fabs")
2339 (set_attr "mode" "DF")])
2340
2341 (define_insn "abssf2"
2342 [(set (match_operand:SF 0 "register_operand" "=f")
2343 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2344 "TARGET_HARD_FLOAT"
2345 "abs.s\t%0,%1"
2346 [(set_attr "type" "fabs")
2347 (set_attr "mode" "SF")])
2348 \f
2349 ;;
2350 ;; ....................
2351 ;;
2352 ;; FIND FIRST BIT INSTRUCTION
2353 ;;
2354 ;; ....................
2355 ;;
2356
2357 (define_insn "ffssi2"
2358 [(set (match_operand:SI 0 "register_operand" "=&d")
2359 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2360 (clobber (match_scratch:SI 2 "=&d"))
2361 (clobber (match_scratch:SI 3 "=&d"))]
2362 "!TARGET_MIPS16"
2363 {
2364 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2365 return "%(\
2366 move\t%0,%.\;\
2367 beq\t%1,%.,2f\n\
2368 %~1:\tand\t%2,%1,0x0001\;\
2369 addu\t%0,%0,1\;\
2370 beq\t%2,%.,1b\;\
2371 srl\t%1,%1,1\n\
2372 %~2:%)";
2373
2374 return "%(\
2375 move\t%0,%.\;\
2376 move\t%3,%1\;\
2377 beq\t%3,%.,2f\n\
2378 %~1:\tand\t%2,%3,0x0001\;\
2379 addu\t%0,%0,1\;\
2380 beq\t%2,%.,1b\;\
2381 srl\t%3,%3,1\n\
2382 %~2:%)";
2383 }
2384 [(set_attr "type" "multi")
2385 (set_attr "mode" "SI")
2386 (set_attr "length" "28")])
2387
2388 (define_insn "ffsdi2"
2389 [(set (match_operand:DI 0 "register_operand" "=&d")
2390 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2391 (clobber (match_scratch:DI 2 "=&d"))
2392 (clobber (match_scratch:DI 3 "=&d"))]
2393 "TARGET_64BIT && !TARGET_MIPS16"
2394 {
2395 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2396 return "%(\
2397 move\t%0,%.\;\
2398 beq\t%1,%.,2f\n\
2399 %~1:\tand\t%2,%1,0x0001\;\
2400 daddu\t%0,%0,1\;\
2401 beq\t%2,%.,1b\;\
2402 dsrl\t%1,%1,1\n\
2403 %~2:%)";
2404
2405 return "%(\
2406 move\t%0,%.\;\
2407 move\t%3,%1\;\
2408 beq\t%3,%.,2f\n\
2409 %~1:\tand\t%2,%3,0x0001\;\
2410 daddu\t%0,%0,1\;\
2411 beq\t%2,%.,1b\;\
2412 dsrl\t%3,%3,1\n\
2413 %~2:%)";
2414 }
2415 [(set_attr "type" "multi")
2416 (set_attr "mode" "DI")
2417 (set_attr "length" "28")])
2418 \f
2419 ;;
2420 ;; ...................
2421 ;;
2422 ;; Count leading zeroes.
2423 ;;
2424 ;; ...................
2425 ;;
2426
2427 (define_insn "clzsi2"
2428 [(set (match_operand:SI 0 "register_operand" "=d")
2429 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2430 "ISA_HAS_CLZ_CLO"
2431 "clz\t%0,%1"
2432 [(set_attr "type" "clz")
2433 (set_attr "mode" "SI")])
2434
2435 (define_insn "clzdi2"
2436 [(set (match_operand:DI 0 "register_operand" "=d")
2437 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2438 "ISA_HAS_DCLZ_DCLO"
2439 "dclz\t%0,%1"
2440 [(set_attr "type" "clz")
2441 (set_attr "mode" "DI")])
2442 \f
2443 ;;
2444 ;; ....................
2445 ;;
2446 ;; NEGATION and ONE'S COMPLEMENT
2447 ;;
2448 ;; ....................
2449
2450 (define_insn "negsi2"
2451 [(set (match_operand:SI 0 "register_operand" "=d")
2452 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2453 ""
2454 {
2455 if (TARGET_MIPS16)
2456 return "neg\t%0,%1";
2457 else
2458 return "subu\t%0,%.,%1";
2459 }
2460 [(set_attr "type" "arith")
2461 (set_attr "mode" "SI")])
2462
2463 (define_insn "negdi2"
2464 [(set (match_operand:DI 0 "register_operand" "=d")
2465 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2466 "TARGET_64BIT && !TARGET_MIPS16"
2467 "dsubu\t%0,%.,%1"
2468 [(set_attr "type" "arith")
2469 (set_attr "mode" "DI")])
2470
2471 (define_insn "negdf2"
2472 [(set (match_operand:DF 0 "register_operand" "=f")
2473 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2474 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2475 "neg.d\t%0,%1"
2476 [(set_attr "type" "fneg")
2477 (set_attr "mode" "DF")])
2478
2479 (define_insn "negsf2"
2480 [(set (match_operand:SF 0 "register_operand" "=f")
2481 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2482 "TARGET_HARD_FLOAT"
2483 "neg.s\t%0,%1"
2484 [(set_attr "type" "fneg")
2485 (set_attr "mode" "SF")])
2486
2487 (define_insn "one_cmplsi2"
2488 [(set (match_operand:SI 0 "register_operand" "=d")
2489 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2490 ""
2491 {
2492 if (TARGET_MIPS16)
2493 return "not\t%0,%1";
2494 else
2495 return "nor\t%0,%.,%1";
2496 }
2497 [(set_attr "type" "arith")
2498 (set_attr "mode" "SI")])
2499
2500 (define_insn "one_cmpldi2"
2501 [(set (match_operand:DI 0 "register_operand" "=d")
2502 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2503 "TARGET_64BIT"
2504 {
2505 if (TARGET_MIPS16)
2506 return "not\t%0,%1";
2507 else
2508 return "nor\t%0,%.,%1";
2509 }
2510 [(set_attr "type" "arith")
2511 (set_attr "mode" "DI")])
2512 \f
2513 ;;
2514 ;; ....................
2515 ;;
2516 ;; LOGICAL
2517 ;;
2518 ;; ....................
2519 ;;
2520
2521 ;; Many of these instructions use trivial define_expands, because we
2522 ;; want to use a different set of constraints when TARGET_MIPS16.
2523
2524 (define_expand "andsi3"
2525 [(set (match_operand:SI 0 "register_operand")
2526 (and:SI (match_operand:SI 1 "uns_arith_operand")
2527 (match_operand:SI 2 "uns_arith_operand")))]
2528 ""
2529 {
2530 if (TARGET_MIPS16)
2531 {
2532 operands[1] = force_reg (SImode, operands[1]);
2533 operands[2] = force_reg (SImode, operands[2]);
2534 }
2535 })
2536
2537 (define_insn ""
2538 [(set (match_operand:SI 0 "register_operand" "=d,d")
2539 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2540 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2541 "!TARGET_MIPS16"
2542 "@
2543 and\t%0,%1,%2
2544 andi\t%0,%1,%x2"
2545 [(set_attr "type" "arith")
2546 (set_attr "mode" "SI")])
2547
2548 (define_insn ""
2549 [(set (match_operand:SI 0 "register_operand" "=d")
2550 (and:SI (match_operand:SI 1 "register_operand" "%0")
2551 (match_operand:SI 2 "register_operand" "d")))]
2552 "TARGET_MIPS16"
2553 "and\t%0,%2"
2554 [(set_attr "type" "arith")
2555 (set_attr "mode" "SI")])
2556
2557 (define_expand "anddi3"
2558 [(set (match_operand:DI 0 "register_operand")
2559 (and:DI (match_operand:DI 1 "register_operand")
2560 (match_operand:DI 2 "uns_arith_operand")))]
2561 "TARGET_64BIT"
2562 {
2563 if (TARGET_MIPS16)
2564 {
2565 operands[1] = force_reg (DImode, operands[1]);
2566 operands[2] = force_reg (DImode, operands[2]);
2567 }
2568 })
2569
2570 (define_insn ""
2571 [(set (match_operand:DI 0 "register_operand" "=d,d")
2572 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2573 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2574 "TARGET_64BIT && !TARGET_MIPS16"
2575 "@
2576 and\t%0,%1,%2
2577 andi\t%0,%1,%x2"
2578 [(set_attr "type" "arith")
2579 (set_attr "mode" "DI")])
2580
2581 (define_insn ""
2582 [(set (match_operand:DI 0 "register_operand" "=d")
2583 (and:DI (match_operand:DI 1 "register_operand" "0")
2584 (match_operand:DI 2 "register_operand" "d")))]
2585 "TARGET_64BIT && TARGET_MIPS16"
2586 "and\t%0,%2"
2587 [(set_attr "type" "arith")
2588 (set_attr "mode" "DI")])
2589
2590 (define_expand "iorsi3"
2591 [(set (match_operand:SI 0 "register_operand")
2592 (ior:SI (match_operand:SI 1 "uns_arith_operand")
2593 (match_operand:SI 2 "uns_arith_operand")))]
2594 ""
2595 {
2596 if (TARGET_MIPS16)
2597 {
2598 operands[1] = force_reg (SImode, operands[1]);
2599 operands[2] = force_reg (SImode, operands[2]);
2600 }
2601 })
2602
2603 (define_insn ""
2604 [(set (match_operand:SI 0 "register_operand" "=d,d")
2605 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2606 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2607 "!TARGET_MIPS16"
2608 "@
2609 or\t%0,%1,%2
2610 ori\t%0,%1,%x2"
2611 [(set_attr "type" "arith")
2612 (set_attr "mode" "SI")])
2613
2614 (define_insn ""
2615 [(set (match_operand:SI 0 "register_operand" "=d")
2616 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2617 (match_operand:SI 2 "register_operand" "d")))]
2618 "TARGET_MIPS16"
2619 "or\t%0,%2"
2620 [(set_attr "type" "arith")
2621 (set_attr "mode" "SI")])
2622
2623 (define_expand "iordi3"
2624 [(set (match_operand:DI 0 "register_operand")
2625 (ior:DI (match_operand:DI 1 "register_operand")
2626 (match_operand:DI 2 "uns_arith_operand")))]
2627 "TARGET_64BIT"
2628 {
2629 if (TARGET_MIPS16)
2630 {
2631 operands[1] = force_reg (DImode, operands[1]);
2632 operands[2] = force_reg (DImode, operands[2]);
2633 }
2634 })
2635
2636 (define_insn ""
2637 [(set (match_operand:DI 0 "register_operand" "=d,d")
2638 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
2639 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2640 "TARGET_64BIT && !TARGET_MIPS16"
2641 "@
2642 or\t%0,%1,%2
2643 ori\t%0,%1,%x2"
2644 [(set_attr "type" "arith")
2645 (set_attr "mode" "DI")])
2646
2647 (define_insn ""
2648 [(set (match_operand:DI 0 "register_operand" "=d")
2649 (ior:DI (match_operand:DI 1 "register_operand" "0")
2650 (match_operand:DI 2 "register_operand" "d")))]
2651 "TARGET_64BIT && TARGET_MIPS16"
2652 "or\t%0,%2"
2653 [(set_attr "type" "arith")
2654 (set_attr "mode" "DI")])
2655
2656 (define_expand "xorsi3"
2657 [(set (match_operand:SI 0 "register_operand")
2658 (xor:SI (match_operand:SI 1 "uns_arith_operand")
2659 (match_operand:SI 2 "uns_arith_operand")))]
2660 ""
2661 "")
2662
2663 (define_insn ""
2664 [(set (match_operand:SI 0 "register_operand" "=d,d")
2665 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2666 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2667 "!TARGET_MIPS16"
2668 "@
2669 xor\t%0,%1,%2
2670 xori\t%0,%1,%x2"
2671 [(set_attr "type" "arith")
2672 (set_attr "mode" "SI")])
2673
2674 (define_insn ""
2675 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
2676 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
2677 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
2678 "TARGET_MIPS16"
2679 "@
2680 xor\t%0,%2
2681 cmpi\t%1,%2
2682 cmp\t%1,%2"
2683 [(set_attr "type" "arith")
2684 (set_attr "mode" "SI")
2685 (set_attr_alternative "length"
2686 [(const_int 4)
2687 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2688 (const_int 4)
2689 (const_int 8))
2690 (const_int 4)])])
2691
2692 (define_expand "xordi3"
2693 [(set (match_operand:DI 0 "register_operand")
2694 (xor:DI (match_operand:DI 1 "register_operand")
2695 (match_operand:DI 2 "uns_arith_operand")))]
2696 "TARGET_64BIT"
2697 {
2698 if (TARGET_MIPS16)
2699 {
2700 operands[1] = force_reg (DImode, operands[1]);
2701 operands[2] = force_reg (DImode, operands[2]);
2702 }
2703 })
2704
2705 (define_insn ""
2706 [(set (match_operand:DI 0 "register_operand" "=d,d")
2707 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
2708 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2709 "TARGET_64BIT && !TARGET_MIPS16"
2710 "@
2711 xor\t%0,%1,%2
2712 xori\t%0,%1,%x2"
2713 [(set_attr "type" "arith")
2714 (set_attr "mode" "DI")])
2715
2716 (define_insn ""
2717 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
2718 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
2719 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2720 "TARGET_64BIT && TARGET_MIPS16"
2721 "@
2722 xor\t%0,%2
2723 cmpi\t%1,%2
2724 cmp\t%1,%2"
2725 [(set_attr "type" "arith")
2726 (set_attr "mode" "DI")
2727 (set_attr_alternative "length"
2728 [(const_int 4)
2729 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2730 (const_int 4)
2731 (const_int 8))
2732 (const_int 4)])])
2733
2734 (define_insn "*norsi3"
2735 [(set (match_operand:SI 0 "register_operand" "=d")
2736 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2737 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2738 "!TARGET_MIPS16"
2739 "nor\t%0,%z1,%z2"
2740 [(set_attr "type" "arith")
2741 (set_attr "mode" "SI")])
2742
2743 (define_insn "*nordi3"
2744 [(set (match_operand:DI 0 "register_operand" "=d")
2745 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
2746 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
2747 "TARGET_64BIT && !TARGET_MIPS16"
2748 "nor\t%0,%z1,%z2"
2749 [(set_attr "type" "arith")
2750 (set_attr "mode" "DI")])
2751 \f
2752 ;;
2753 ;; ....................
2754 ;;
2755 ;; TRUNCATION
2756 ;;
2757 ;; ....................
2758
2759
2760
2761 (define_insn "truncdfsf2"
2762 [(set (match_operand:SF 0 "register_operand" "=f")
2763 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2764 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2765 "cvt.s.d\t%0,%1"
2766 [(set_attr "type" "fcvt")
2767 (set_attr "mode" "SF")])
2768
2769 ;; Integer truncation patterns. Truncating SImode values to smaller
2770 ;; modes is a no-op, as it is for most other GCC ports. Truncating
2771 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2772 ;; need to make sure that the lower 32 bits are properly sign-extended
2773 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
2774 ;; smaller than SImode is equivalent to two separate truncations:
2775 ;;
2776 ;; A B
2777 ;; DI ---> HI == DI ---> SI ---> HI
2778 ;; DI ---> QI == DI ---> SI ---> QI
2779 ;;
2780 ;; Step A needs a real instruction but step B does not.
2781
2782 (define_insn "truncdisi2"
2783 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2784 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2785 "TARGET_64BIT"
2786 "@
2787 sll\t%0,%1,0
2788 sw\t%1,%0"
2789 [(set_attr "type" "shift,store")
2790 (set_attr "mode" "SI")
2791 (set_attr "extended_mips16" "yes,*")])
2792
2793 (define_insn "truncdihi2"
2794 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2795 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2796 "TARGET_64BIT"
2797 "@
2798 sll\t%0,%1,0
2799 sh\t%1,%0"
2800 [(set_attr "type" "shift,store")
2801 (set_attr "mode" "SI")
2802 (set_attr "extended_mips16" "yes,*")])
2803
2804 (define_insn "truncdiqi2"
2805 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2806 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2807 "TARGET_64BIT"
2808 "@
2809 sll\t%0,%1,0
2810 sb\t%1,%0"
2811 [(set_attr "type" "shift,store")
2812 (set_attr "mode" "SI")
2813 (set_attr "extended_mips16" "yes,*")])
2814
2815 ;; Combiner patterns to optimize shift/truncate combinations.
2816
2817 (define_insn ""
2818 [(set (match_operand:SI 0 "register_operand" "=d")
2819 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2820 (match_operand:DI 2 "small_int" "I"))))]
2821 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2822 "dsra\t%0,%1,%2"
2823 [(set_attr "type" "shift")
2824 (set_attr "mode" "SI")])
2825
2826 (define_insn ""
2827 [(set (match_operand:SI 0 "register_operand" "=d")
2828 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2829 (const_int 32))))]
2830 "TARGET_64BIT && !TARGET_MIPS16"
2831 "dsra\t%0,%1,32"
2832 [(set_attr "type" "shift")
2833 (set_attr "mode" "SI")])
2834
2835
2836 ;; Combiner patterns for truncate/sign_extend combinations. They use
2837 ;; the shift/truncate patterns above.
2838
2839 (define_insn_and_split ""
2840 [(set (match_operand:SI 0 "register_operand" "=d")
2841 (sign_extend:SI
2842 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2843 "TARGET_64BIT && !TARGET_MIPS16"
2844 "#"
2845 "&& reload_completed"
2846 [(set (match_dup 2)
2847 (ashift:DI (match_dup 1)
2848 (const_int 48)))
2849 (set (match_dup 0)
2850 (truncate:SI (ashiftrt:DI (match_dup 2)
2851 (const_int 48))))]
2852 { operands[2] = gen_lowpart (DImode, operands[0]); })
2853
2854 (define_insn_and_split ""
2855 [(set (match_operand:SI 0 "register_operand" "=d")
2856 (sign_extend:SI
2857 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2858 "TARGET_64BIT && !TARGET_MIPS16"
2859 "#"
2860 "&& reload_completed"
2861 [(set (match_dup 2)
2862 (ashift:DI (match_dup 1)
2863 (const_int 56)))
2864 (set (match_dup 0)
2865 (truncate:SI (ashiftrt:DI (match_dup 2)
2866 (const_int 56))))]
2867 { operands[2] = gen_lowpart (DImode, operands[0]); })
2868
2869
2870 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2871
2872 (define_insn ""
2873 [(set (match_operand:SI 0 "register_operand" "=d")
2874 (zero_extend:SI (truncate:HI
2875 (match_operand:DI 1 "register_operand" "d"))))]
2876 "TARGET_64BIT && !TARGET_MIPS16"
2877 "andi\t%0,%1,0xffff"
2878 [(set_attr "type" "arith")
2879 (set_attr "mode" "SI")])
2880
2881 (define_insn ""
2882 [(set (match_operand:SI 0 "register_operand" "=d")
2883 (zero_extend:SI (truncate:QI
2884 (match_operand:DI 1 "register_operand" "d"))))]
2885 "TARGET_64BIT && !TARGET_MIPS16"
2886 "andi\t%0,%1,0xff"
2887 [(set_attr "type" "arith")
2888 (set_attr "mode" "SI")])
2889
2890 (define_insn ""
2891 [(set (match_operand:HI 0 "register_operand" "=d")
2892 (zero_extend:HI (truncate:QI
2893 (match_operand:DI 1 "register_operand" "d"))))]
2894 "TARGET_64BIT && !TARGET_MIPS16"
2895 "andi\t%0,%1,0xff"
2896 [(set_attr "type" "arith")
2897 (set_attr "mode" "HI")])
2898 \f
2899 ;;
2900 ;; ....................
2901 ;;
2902 ;; ZERO EXTENSION
2903 ;;
2904 ;; ....................
2905
2906 ;; Extension insns.
2907 ;; Those for integer source operand are ordered widest source type first.
2908
2909 (define_insn_and_split "zero_extendsidi2"
2910 [(set (match_operand:DI 0 "register_operand" "=d")
2911 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2912 "TARGET_64BIT"
2913 "#"
2914 "&& reload_completed"
2915 [(set (match_dup 0)
2916 (ashift:DI (match_dup 1) (const_int 32)))
2917 (set (match_dup 0)
2918 (lshiftrt:DI (match_dup 0) (const_int 32)))]
2919 "operands[1] = gen_lowpart (DImode, operands[1]);"
2920 [(set_attr "type" "multi")
2921 (set_attr "mode" "DI")
2922 (set_attr "length" "8")])
2923
2924 (define_insn "*zero_extendsidi2_mem"
2925 [(set (match_operand:DI 0 "register_operand" "=d")
2926 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2927 "TARGET_64BIT"
2928 "lwu\t%0,%1"
2929 [(set_attr "type" "load")
2930 (set_attr "mode" "DI")])
2931
2932 (define_expand "zero_extendhisi2"
2933 [(set (match_operand:SI 0 "register_operand")
2934 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2935 ""
2936 {
2937 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2938 {
2939 rtx op = gen_lowpart (SImode, operands[1]);
2940 rtx temp = force_reg (SImode, GEN_INT (0xffff));
2941
2942 emit_insn (gen_andsi3 (operands[0], op, temp));
2943 DONE;
2944 }
2945 })
2946
2947 (define_insn ""
2948 [(set (match_operand:SI 0 "register_operand" "=d,d")
2949 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2950 "!TARGET_MIPS16"
2951 "@
2952 andi\t%0,%1,0xffff
2953 lhu\t%0,%1"
2954 [(set_attr "type" "arith,load")
2955 (set_attr "mode" "SI")
2956 (set_attr "length" "4,*")])
2957
2958 (define_insn ""
2959 [(set (match_operand:SI 0 "register_operand" "=d")
2960 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2961 "TARGET_MIPS16"
2962 "lhu\t%0,%1"
2963 [(set_attr "type" "load")
2964 (set_attr "mode" "SI")])
2965
2966 (define_expand "zero_extendhidi2"
2967 [(set (match_operand:DI 0 "register_operand")
2968 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2969 "TARGET_64BIT"
2970 {
2971 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2972 {
2973 rtx op = gen_lowpart (DImode, operands[1]);
2974 rtx temp = force_reg (DImode, GEN_INT (0xffff));
2975
2976 emit_insn (gen_anddi3 (operands[0], op, temp));
2977 DONE;
2978 }
2979 })
2980
2981 (define_insn ""
2982 [(set (match_operand:DI 0 "register_operand" "=d,d")
2983 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2984 "TARGET_64BIT && !TARGET_MIPS16"
2985 "@
2986 andi\t%0,%1,0xffff
2987 lhu\t%0,%1"
2988 [(set_attr "type" "arith,load")
2989 (set_attr "mode" "DI")
2990 (set_attr "length" "4,*")])
2991
2992 (define_insn ""
2993 [(set (match_operand:DI 0 "register_operand" "=d")
2994 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2995 "TARGET_64BIT && TARGET_MIPS16"
2996 "lhu\t%0,%1"
2997 [(set_attr "type" "load")
2998 (set_attr "mode" "DI")])
2999
3000 (define_expand "zero_extendqihi2"
3001 [(set (match_operand:HI 0 "register_operand")
3002 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3003 ""
3004 {
3005 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3006 {
3007 rtx op0 = gen_lowpart (SImode, operands[0]);
3008 rtx op1 = gen_lowpart (SImode, operands[1]);
3009 rtx temp = force_reg (SImode, GEN_INT (0xff));
3010
3011 emit_insn (gen_andsi3 (op0, op1, temp));
3012 DONE;
3013 }
3014 })
3015
3016 (define_insn ""
3017 [(set (match_operand:HI 0 "register_operand" "=d,d")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3019 "!TARGET_MIPS16"
3020 "@
3021 andi\t%0,%1,0x00ff
3022 lbu\t%0,%1"
3023 [(set_attr "type" "arith,load")
3024 (set_attr "mode" "HI")
3025 (set_attr "length" "4,*")])
3026
3027 (define_insn ""
3028 [(set (match_operand:HI 0 "register_operand" "=d")
3029 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3030 "TARGET_MIPS16"
3031 "lbu\t%0,%1"
3032 [(set_attr "type" "load")
3033 (set_attr "mode" "HI")])
3034
3035 (define_expand "zero_extendqisi2"
3036 [(set (match_operand:SI 0 "register_operand")
3037 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3038 ""
3039 {
3040 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3041 {
3042 rtx op = gen_lowpart (SImode, operands[1]);
3043 rtx temp = force_reg (SImode, GEN_INT (0xff));
3044
3045 emit_insn (gen_andsi3 (operands[0], op, temp));
3046 DONE;
3047 }
3048 })
3049
3050 (define_insn ""
3051 [(set (match_operand:SI 0 "register_operand" "=d,d")
3052 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3053 "!TARGET_MIPS16"
3054 "@
3055 andi\t%0,%1,0x00ff
3056 lbu\t%0,%1"
3057 [(set_attr "type" "arith,load")
3058 (set_attr "mode" "SI")
3059 (set_attr "length" "4,*")])
3060
3061 (define_insn ""
3062 [(set (match_operand:SI 0 "register_operand" "=d")
3063 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3064 "TARGET_MIPS16"
3065 "lbu\t%0,%1"
3066 [(set_attr "type" "load")
3067 (set_attr "mode" "SI")])
3068
3069 (define_expand "zero_extendqidi2"
3070 [(set (match_operand:DI 0 "register_operand")
3071 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3072 "TARGET_64BIT"
3073 {
3074 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3075 {
3076 rtx op = gen_lowpart (DImode, operands[1]);
3077 rtx temp = force_reg (DImode, GEN_INT (0xff));
3078
3079 emit_insn (gen_anddi3 (operands[0], op, temp));
3080 DONE;
3081 }
3082 })
3083
3084 (define_insn ""
3085 [(set (match_operand:DI 0 "register_operand" "=d,d")
3086 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3087 "TARGET_64BIT && !TARGET_MIPS16"
3088 "@
3089 andi\t%0,%1,0x00ff
3090 lbu\t%0,%1"
3091 [(set_attr "type" "arith,load")
3092 (set_attr "mode" "DI")
3093 (set_attr "length" "4,*")])
3094
3095 (define_insn ""
3096 [(set (match_operand:DI 0 "register_operand" "=d")
3097 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3098 "TARGET_64BIT && TARGET_MIPS16"
3099 "lbu\t%0,%1"
3100 [(set_attr "type" "load")
3101 (set_attr "mode" "DI")])
3102 \f
3103 ;;
3104 ;; ....................
3105 ;;
3106 ;; SIGN EXTENSION
3107 ;;
3108 ;; ....................
3109
3110 ;; Extension insns.
3111 ;; Those for integer source operand are ordered widest source type first.
3112
3113 ;; When TARGET_64BIT, all SImode integer registers should already be in
3114 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can
3115 ;; therefore get rid of register->register instructions if we constrain
3116 ;; the source to be in the same register as the destination.
3117 ;;
3118 ;; The register alternative has type "arith" so that the pre-reload
3119 ;; scheduler will treat it as a move. This reflects what happens if
3120 ;; the register alternative needs a reload.
3121 (define_insn_and_split "extendsidi2"
3122 [(set (match_operand:DI 0 "register_operand" "=d,d")
3123 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
3124 "TARGET_64BIT"
3125 "@
3126 #
3127 lw\t%0,%1"
3128 "&& reload_completed && register_operand (operands[1], VOIDmode)"
3129 [(const_int 0)]
3130 {
3131 emit_note (NOTE_INSN_DELETED);
3132 DONE;
3133 }
3134 [(set_attr "type" "arith,load")
3135 (set_attr "mode" "DI")])
3136
3137 ;; These patterns originally accepted general_operands, however, slightly
3138 ;; better code is generated by only accepting register_operands, and then
3139 ;; letting combine generate the lh and lb insns.
3140
3141 ;; These expanders originally put values in registers first. We split
3142 ;; all non-mem patterns after reload.
3143
3144 (define_expand "extendhidi2"
3145 [(set (match_operand:DI 0 "register_operand")
3146 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
3147 "TARGET_64BIT"
3148 "")
3149
3150 (define_insn "*extendhidi2"
3151 [(set (match_operand:DI 0 "register_operand" "=d")
3152 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3153 "TARGET_64BIT"
3154 "#")
3155
3156 (define_split
3157 [(set (match_operand:DI 0 "register_operand")
3158 (sign_extend:DI (match_operand:HI 1 "register_operand")))]
3159 "TARGET_64BIT && reload_completed"
3160 [(set (match_dup 0)
3161 (ashift:DI (match_dup 1) (const_int 48)))
3162 (set (match_dup 0)
3163 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3164 "operands[1] = gen_lowpart (DImode, operands[1]);")
3165
3166 (define_insn "*extendhidi2_mem"
3167 [(set (match_operand:DI 0 "register_operand" "=d")
3168 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3169 "TARGET_64BIT"
3170 "lh\t%0,%1"
3171 [(set_attr "type" "load")
3172 (set_attr "mode" "DI")])
3173
3174 (define_expand "extendhisi2"
3175 [(set (match_operand:SI 0 "register_operand")
3176 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
3177 ""
3178 {
3179 if (ISA_HAS_SEB_SEH)
3180 {
3181 emit_insn (gen_extendhisi2_hw (operands[0],
3182 force_reg (HImode, operands[1])));
3183 DONE;
3184 }
3185 })
3186
3187 (define_insn "*extendhisi2"
3188 [(set (match_operand:SI 0 "register_operand" "=d")
3189 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3190 ""
3191 "#")
3192
3193 (define_split
3194 [(set (match_operand:SI 0 "register_operand")
3195 (sign_extend:SI (match_operand:HI 1 "register_operand")))]
3196 "reload_completed"
3197 [(set (match_dup 0)
3198 (ashift:SI (match_dup 1) (const_int 16)))
3199 (set (match_dup 0)
3200 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3201 "operands[1] = gen_lowpart (SImode, operands[1]);")
3202
3203 (define_insn "extendhisi2_mem"
3204 [(set (match_operand:SI 0 "register_operand" "=d")
3205 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3206 ""
3207 "lh\t%0,%1"
3208 [(set_attr "type" "load")
3209 (set_attr "mode" "SI")])
3210
3211 (define_insn "extendhisi2_hw"
3212 [(set (match_operand:SI 0 "register_operand" "=r")
3213 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3214 "ISA_HAS_SEB_SEH"
3215 "seh\t%0,%1"
3216 [(set_attr "type" "arith")
3217 (set_attr "mode" "SI")])
3218
3219 (define_expand "extendqihi2"
3220 [(set (match_operand:HI 0 "register_operand")
3221 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3222 ""
3223 "")
3224
3225 (define_insn "*extendqihi2"
3226 [(set (match_operand:HI 0 "register_operand" "=d")
3227 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3228 ""
3229 "#")
3230
3231 (define_split
3232 [(set (match_operand:HI 0 "register_operand")
3233 (sign_extend:HI (match_operand:QI 1 "register_operand")))]
3234 "reload_completed"
3235 [(set (match_dup 0)
3236 (ashift:SI (match_dup 1) (const_int 24)))
3237 (set (match_dup 0)
3238 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3239 "operands[0] = gen_lowpart (SImode, operands[0]);
3240 operands[1] = gen_lowpart (SImode, operands[1]);")
3241
3242 (define_insn "*extendqihi2_internal_mem"
3243 [(set (match_operand:HI 0 "register_operand" "=d")
3244 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3245 ""
3246 "lb\t%0,%1"
3247 [(set_attr "type" "load")
3248 (set_attr "mode" "SI")])
3249
3250
3251 (define_expand "extendqisi2"
3252 [(set (match_operand:SI 0 "register_operand")
3253 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
3254 ""
3255 {
3256 if (ISA_HAS_SEB_SEH)
3257 {
3258 emit_insn (gen_extendqisi2_hw (operands[0],
3259 force_reg (QImode, operands[1])));
3260 DONE;
3261 }
3262 })
3263
3264 (define_insn "*extendqisi2"
3265 [(set (match_operand:SI 0 "register_operand" "=d")
3266 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3267 ""
3268 "#")
3269
3270 (define_split
3271 [(set (match_operand:SI 0 "register_operand")
3272 (sign_extend:SI (match_operand:QI 1 "register_operand")))]
3273 "reload_completed"
3274 [(set (match_dup 0)
3275 (ashift:SI (match_dup 1) (const_int 24)))
3276 (set (match_dup 0)
3277 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3278 "operands[1] = gen_lowpart (SImode, operands[1]);")
3279
3280 (define_insn "*extendqisi2_mem"
3281 [(set (match_operand:SI 0 "register_operand" "=d")
3282 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3283 ""
3284 "lb\t%0,%1"
3285 [(set_attr "type" "load")
3286 (set_attr "mode" "SI")])
3287
3288 (define_insn "extendqisi2_hw"
3289 [(set (match_operand:SI 0 "register_operand" "=r")
3290 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3291 "ISA_HAS_SEB_SEH"
3292 "seb\t%0,%1"
3293 [(set_attr "type" "arith")
3294 (set_attr "mode" "SI")])
3295
3296 (define_expand "extendqidi2"
3297 [(set (match_operand:DI 0 "register_operand")
3298 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
3299 "TARGET_64BIT"
3300 "")
3301
3302 (define_insn "*extendqidi2"
3303 [(set (match_operand:DI 0 "register_operand" "=d")
3304 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3305 "TARGET_64BIT"
3306 "#")
3307
3308 (define_split
3309 [(set (match_operand:DI 0 "register_operand")
3310 (sign_extend:DI (match_operand:QI 1 "register_operand")))]
3311 "TARGET_64BIT && reload_completed"
3312 [(set (match_dup 0)
3313 (ashift:DI (match_dup 1) (const_int 56)))
3314 (set (match_dup 0)
3315 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3316 "operands[1] = gen_lowpart (DImode, operands[1]);")
3317
3318 (define_insn "*extendqidi2_mem"
3319 [(set (match_operand:DI 0 "register_operand" "=d")
3320 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3321 "TARGET_64BIT"
3322 "lb\t%0,%1"
3323 [(set_attr "type" "load")
3324 (set_attr "mode" "DI")])
3325
3326 (define_insn "extendsfdf2"
3327 [(set (match_operand:DF 0 "register_operand" "=f")
3328 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3329 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3330 "cvt.d.s\t%0,%1"
3331 [(set_attr "type" "fcvt")
3332 (set_attr "mode" "DF")])
3333 \f
3334 ;;
3335 ;; ....................
3336 ;;
3337 ;; CONVERSIONS
3338 ;;
3339 ;; ....................
3340
3341 (define_expand "fix_truncdfsi2"
3342 [(set (match_operand:SI 0 "register_operand")
3343 (fix:SI (match_operand:DF 1 "register_operand")))]
3344 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3345 {
3346 if (!ISA_HAS_TRUNC_W)
3347 {
3348 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3349 DONE;
3350 }
3351 })
3352
3353 (define_insn "fix_truncdfsi2_insn"
3354 [(set (match_operand:SI 0 "register_operand" "=f")
3355 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3356 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3357 "trunc.w.d %0,%1"
3358 [(set_attr "type" "fcvt")
3359 (set_attr "mode" "DF")
3360 (set_attr "length" "4")])
3361
3362 (define_insn "fix_truncdfsi2_macro"
3363 [(set (match_operand:SI 0 "register_operand" "=f")
3364 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3365 (clobber (match_scratch:DF 2 "=d"))]
3366 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3367 {
3368 if (set_nomacro)
3369 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3370 else
3371 return "trunc.w.d %0,%1,%2";
3372 }
3373 [(set_attr "type" "fcvt")
3374 (set_attr "mode" "DF")
3375 (set_attr "length" "36")])
3376
3377 (define_expand "fix_truncsfsi2"
3378 [(set (match_operand:SI 0 "register_operand")
3379 (fix:SI (match_operand:SF 1 "register_operand")))]
3380 "TARGET_HARD_FLOAT"
3381 {
3382 if (!ISA_HAS_TRUNC_W)
3383 {
3384 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3385 DONE;
3386 }
3387 })
3388
3389 (define_insn "fix_truncsfsi2_insn"
3390 [(set (match_operand:SI 0 "register_operand" "=f")
3391 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3392 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3393 "trunc.w.s %0,%1"
3394 [(set_attr "type" "fcvt")
3395 (set_attr "mode" "DF")
3396 (set_attr "length" "4")])
3397
3398 (define_insn "fix_truncsfsi2_macro"
3399 [(set (match_operand:SI 0 "register_operand" "=f")
3400 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3401 (clobber (match_scratch:SF 2 "=d"))]
3402 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3403 {
3404 if (set_nomacro)
3405 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3406 else
3407 return "trunc.w.s %0,%1,%2";
3408 }
3409 [(set_attr "type" "fcvt")
3410 (set_attr "mode" "DF")
3411 (set_attr "length" "36")])
3412
3413
3414 (define_insn "fix_truncdfdi2"
3415 [(set (match_operand:DI 0 "register_operand" "=f")
3416 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3417 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3418 "trunc.l.d %0,%1"
3419 [(set_attr "type" "fcvt")
3420 (set_attr "mode" "DF")
3421 (set_attr "length" "4")])
3422
3423
3424 (define_insn "fix_truncsfdi2"
3425 [(set (match_operand:DI 0 "register_operand" "=f")
3426 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3427 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3428 "trunc.l.s %0,%1"
3429 [(set_attr "type" "fcvt")
3430 (set_attr "mode" "SF")
3431 (set_attr "length" "4")])
3432
3433
3434 (define_insn "floatsidf2"
3435 [(set (match_operand:DF 0 "register_operand" "=f")
3436 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3437 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3438 "cvt.d.w\t%0,%1"
3439 [(set_attr "type" "fcvt")
3440 (set_attr "mode" "DF")
3441 (set_attr "length" "4")])
3442
3443
3444 (define_insn "floatdidf2"
3445 [(set (match_operand:DF 0 "register_operand" "=f")
3446 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3447 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3448 "cvt.d.l\t%0,%1"
3449 [(set_attr "type" "fcvt")
3450 (set_attr "mode" "DF")
3451 (set_attr "length" "4")])
3452
3453
3454 (define_insn "floatsisf2"
3455 [(set (match_operand:SF 0 "register_operand" "=f")
3456 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3457 "TARGET_HARD_FLOAT"
3458 "cvt.s.w\t%0,%1"
3459 [(set_attr "type" "fcvt")
3460 (set_attr "mode" "SF")
3461 (set_attr "length" "4")])
3462
3463
3464 (define_insn "floatdisf2"
3465 [(set (match_operand:SF 0 "register_operand" "=f")
3466 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3467 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3468 "cvt.s.l\t%0,%1"
3469 [(set_attr "type" "fcvt")
3470 (set_attr "mode" "SF")
3471 (set_attr "length" "4")])
3472
3473
3474 (define_expand "fixuns_truncdfsi2"
3475 [(set (match_operand:SI 0 "register_operand")
3476 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
3477 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3478 {
3479 rtx reg1 = gen_reg_rtx (DFmode);
3480 rtx reg2 = gen_reg_rtx (DFmode);
3481 rtx reg3 = gen_reg_rtx (SImode);
3482 rtx label1 = gen_label_rtx ();
3483 rtx label2 = gen_label_rtx ();
3484 REAL_VALUE_TYPE offset;
3485
3486 real_2expN (&offset, 31);
3487
3488 if (reg1) /* Turn off complaints about unreached code. */
3489 {
3490 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3491 do_pending_stack_adjust ();
3492
3493 emit_insn (gen_cmpdf (operands[1], reg1));
3494 emit_jump_insn (gen_bge (label1));
3495
3496 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3497 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3498 gen_rtx_LABEL_REF (VOIDmode, label2)));
3499 emit_barrier ();
3500
3501 emit_label (label1);
3502 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3503 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3504 (BITMASK_HIGH, SImode)));
3505
3506 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3507 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3508
3509 emit_label (label2);
3510
3511 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3512 fields, and can't be used for REG_NOTES anyway). */
3513 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3514 DONE;
3515 }
3516 })
3517
3518
3519 (define_expand "fixuns_truncdfdi2"
3520 [(set (match_operand:DI 0 "register_operand")
3521 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
3522 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3523 {
3524 rtx reg1 = gen_reg_rtx (DFmode);
3525 rtx reg2 = gen_reg_rtx (DFmode);
3526 rtx reg3 = gen_reg_rtx (DImode);
3527 rtx label1 = gen_label_rtx ();
3528 rtx label2 = gen_label_rtx ();
3529 REAL_VALUE_TYPE offset;
3530
3531 real_2expN (&offset, 63);
3532
3533 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3534 do_pending_stack_adjust ();
3535
3536 emit_insn (gen_cmpdf (operands[1], reg1));
3537 emit_jump_insn (gen_bge (label1));
3538
3539 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3540 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3541 gen_rtx_LABEL_REF (VOIDmode, label2)));
3542 emit_barrier ();
3543
3544 emit_label (label1);
3545 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3546 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3547 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3548
3549 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3550 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3551
3552 emit_label (label2);
3553
3554 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3555 fields, and can't be used for REG_NOTES anyway). */
3556 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3557 DONE;
3558 })
3559
3560
3561 (define_expand "fixuns_truncsfsi2"
3562 [(set (match_operand:SI 0 "register_operand")
3563 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
3564 "TARGET_HARD_FLOAT"
3565 {
3566 rtx reg1 = gen_reg_rtx (SFmode);
3567 rtx reg2 = gen_reg_rtx (SFmode);
3568 rtx reg3 = gen_reg_rtx (SImode);
3569 rtx label1 = gen_label_rtx ();
3570 rtx label2 = gen_label_rtx ();
3571 REAL_VALUE_TYPE offset;
3572
3573 real_2expN (&offset, 31);
3574
3575 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3576 do_pending_stack_adjust ();
3577
3578 emit_insn (gen_cmpsf (operands[1], reg1));
3579 emit_jump_insn (gen_bge (label1));
3580
3581 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3582 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3583 gen_rtx_LABEL_REF (VOIDmode, label2)));
3584 emit_barrier ();
3585
3586 emit_label (label1);
3587 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3588 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3589 (BITMASK_HIGH, SImode)));
3590
3591 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3592 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3593
3594 emit_label (label2);
3595
3596 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3597 fields, and can't be used for REG_NOTES anyway). */
3598 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3599 DONE;
3600 })
3601
3602
3603 (define_expand "fixuns_truncsfdi2"
3604 [(set (match_operand:DI 0 "register_operand")
3605 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
3606 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3607 {
3608 rtx reg1 = gen_reg_rtx (SFmode);
3609 rtx reg2 = gen_reg_rtx (SFmode);
3610 rtx reg3 = gen_reg_rtx (DImode);
3611 rtx label1 = gen_label_rtx ();
3612 rtx label2 = gen_label_rtx ();
3613 REAL_VALUE_TYPE offset;
3614
3615 real_2expN (&offset, 63);
3616
3617 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3618 do_pending_stack_adjust ();
3619
3620 emit_insn (gen_cmpsf (operands[1], reg1));
3621 emit_jump_insn (gen_bge (label1));
3622
3623 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3624 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3625 gen_rtx_LABEL_REF (VOIDmode, label2)));
3626 emit_barrier ();
3627
3628 emit_label (label1);
3629 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3630 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3631 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3632
3633 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3634 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3635
3636 emit_label (label2);
3637
3638 /* Allow REG_NOTES to be set on last insn (labels don't have enough
3639 fields, and can't be used for REG_NOTES anyway). */
3640 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3641 DONE;
3642 })
3643 \f
3644 ;;
3645 ;; ....................
3646 ;;
3647 ;; DATA MOVEMENT
3648 ;;
3649 ;; ....................
3650
3651 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
3652
3653 (define_expand "extv"
3654 [(set (match_operand 0 "register_operand")
3655 (sign_extract (match_operand:QI 1 "memory_operand")
3656 (match_operand 2 "immediate_operand")
3657 (match_operand 3 "immediate_operand")))]
3658 "!TARGET_MIPS16"
3659 {
3660 if (mips_expand_unaligned_load (operands[0], operands[1],
3661 INTVAL (operands[2]),
3662 INTVAL (operands[3])))
3663 DONE;
3664 else
3665 FAIL;
3666 })
3667
3668 (define_expand "extzv"
3669 [(set (match_operand 0 "register_operand")
3670 (zero_extract (match_operand:QI 1 "memory_operand")
3671 (match_operand 2 "immediate_operand")
3672 (match_operand 3 "immediate_operand")))]
3673 "!TARGET_MIPS16"
3674 {
3675 if (mips_expand_unaligned_load (operands[0], operands[1],
3676 INTVAL (operands[2]),
3677 INTVAL (operands[3])))
3678 DONE;
3679 else
3680 FAIL;
3681 })
3682
3683 (define_expand "insv"
3684 [(set (zero_extract (match_operand:QI 0 "memory_operand")
3685 (match_operand 1 "immediate_operand")
3686 (match_operand 2 "immediate_operand"))
3687 (match_operand 3 "reg_or_0_operand"))]
3688 "!TARGET_MIPS16"
3689 {
3690 if (mips_expand_unaligned_store (operands[0], operands[3],
3691 INTVAL (operands[1]),
3692 INTVAL (operands[2])))
3693 DONE;
3694 else
3695 FAIL;
3696 })
3697
3698 ;; Unaligned word moves generated by the bit field patterns.
3699 ;;
3700 ;; As far as the rtl is concerned, both the left-part and right-part
3701 ;; instructions can access the whole field. However, the real operand
3702 ;; refers to just the first or the last byte (depending on endianness).
3703 ;; We therefore use two memory operands to each instruction, one to
3704 ;; describe the rtl effect and one to use in the assembly output.
3705 ;;
3706 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3707 ;; This allows us to use the standard length calculations for the "load"
3708 ;; and "store" type attributes.
3709
3710 (define_insn "mov_lwl"
3711 [(set (match_operand:SI 0 "register_operand" "=d")
3712 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3713 (match_operand:QI 2 "memory_operand" "m")]
3714 UNSPEC_LWL))]
3715 "!TARGET_MIPS16"
3716 "lwl\t%0,%2"
3717 [(set_attr "type" "load")
3718 (set_attr "mode" "SI")
3719 (set_attr "hazard" "none")])
3720
3721 (define_insn "mov_lwr"
3722 [(set (match_operand:SI 0 "register_operand" "=d")
3723 (unspec:SI [(match_operand:BLK 1 "memory_operand" "m")
3724 (match_operand:QI 2 "memory_operand" "m")
3725 (match_operand:SI 3 "register_operand" "0")]
3726 UNSPEC_LWR))]
3727 "!TARGET_MIPS16"
3728 "lwr\t%0,%2"
3729 [(set_attr "type" "load")
3730 (set_attr "mode" "SI")])
3731
3732
3733 (define_insn "mov_swl"
3734 [(set (match_operand:BLK 0 "memory_operand" "=m")
3735 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3736 (match_operand:QI 2 "memory_operand" "m")]
3737 UNSPEC_SWL))]
3738 "!TARGET_MIPS16"
3739 "swl\t%z1,%2"
3740 [(set_attr "type" "store")
3741 (set_attr "mode" "SI")])
3742
3743 (define_insn "mov_swr"
3744 [(set (match_operand:BLK 0 "memory_operand" "+m")
3745 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
3746 (match_operand:QI 2 "memory_operand" "m")
3747 (match_dup 0)]
3748 UNSPEC_SWR))]
3749 "!TARGET_MIPS16"
3750 "swr\t%z1,%2"
3751 [(set_attr "type" "store")
3752 (set_attr "mode" "SI")])
3753
3754
3755 (define_insn "mov_ldl"
3756 [(set (match_operand:DI 0 "register_operand" "=d")
3757 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3758 (match_operand:QI 2 "memory_operand" "m")]
3759 UNSPEC_LDL))]
3760 "TARGET_64BIT && !TARGET_MIPS16"
3761 "ldl\t%0,%2"
3762 [(set_attr "type" "load")
3763 (set_attr "mode" "DI")])
3764
3765 (define_insn "mov_ldr"
3766 [(set (match_operand:DI 0 "register_operand" "=d")
3767 (unspec:DI [(match_operand:BLK 1 "memory_operand" "m")
3768 (match_operand:QI 2 "memory_operand" "m")
3769 (match_operand:DI 3 "register_operand" "0")]
3770 UNSPEC_LDR))]
3771 "TARGET_64BIT && !TARGET_MIPS16"
3772 "ldr\t%0,%2"
3773 [(set_attr "type" "load")
3774 (set_attr "mode" "DI")])
3775
3776
3777 (define_insn "mov_sdl"
3778 [(set (match_operand:BLK 0 "memory_operand" "=m")
3779 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3780 (match_operand:QI 2 "memory_operand" "m")]
3781 UNSPEC_SDL))]
3782 "TARGET_64BIT && !TARGET_MIPS16"
3783 "sdl\t%z1,%2"
3784 [(set_attr "type" "store")
3785 (set_attr "mode" "DI")])
3786
3787 (define_insn "mov_sdr"
3788 [(set (match_operand:BLK 0 "memory_operand" "+m")
3789 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
3790 (match_operand:QI 2 "memory_operand" "m")
3791 (match_dup 0)]
3792 UNSPEC_SDR))]
3793 "TARGET_64BIT && !TARGET_MIPS16"
3794 "sdr\t%z1,%2"
3795 [(set_attr "type" "store")
3796 (set_attr "mode" "DI")])
3797
3798 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3799 ;; The required value is:
3800 ;;
3801 ;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3802 ;;
3803 ;; which translates to:
3804 ;;
3805 ;; lui op0,%highest(op1)
3806 ;; daddiu op0,op0,%higher(op1)
3807 ;; dsll op0,op0,16
3808 ;; daddiu op0,op0,%hi(op1)
3809 ;; dsll op0,op0,16
3810 (define_insn_and_split "*lea_high64"
3811 [(set (match_operand:DI 0 "register_operand" "=d")
3812 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3813 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3814 "#"
3815 "&& reload_completed"
3816 [(set (match_dup 0) (high:DI (match_dup 2)))
3817 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3818 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3819 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3820 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3821 {
3822 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3823 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3824 }
3825 [(set_attr "length" "20")])
3826
3827 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3828 ;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine
3829 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3830 ;; used once. We can then use the sequence:
3831 ;;
3832 ;; lui op0,%highest(op1)
3833 ;; lui op2,%hi(op1)
3834 ;; daddiu op0,op0,%higher(op1)
3835 ;; daddiu op2,op2,%lo(op1)
3836 ;; dsll32 op0,op0,0
3837 ;; daddu op0,op0,op2
3838 ;;
3839 ;; which takes 4 cycles on most superscalar targets.
3840 (define_insn_and_split "*lea64"
3841 [(set (match_operand:DI 0 "register_operand" "=d")
3842 (match_operand:DI 1 "general_symbolic_operand" ""))
3843 (clobber (match_scratch:DI 2 "=&d"))]
3844 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3845 "#"
3846 "&& reload_completed"
3847 [(set (match_dup 0) (high:DI (match_dup 3)))
3848 (set (match_dup 2) (high:DI (match_dup 4)))
3849 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3850 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3851 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3852 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3853 {
3854 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3855 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3856 }
3857 [(set_attr "length" "24")])
3858
3859 ;; Insns to fetch a global symbol from a big GOT.
3860
3861 (define_insn_and_split "*xgot_hisi"
3862 [(set (match_operand:SI 0 "register_operand" "=d")
3863 (high:SI (match_operand:SI 1 "global_got_operand" "")))]
3864 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3865 "#"
3866 "&& reload_completed"
3867 [(set (match_dup 0) (high:SI (match_dup 2)))
3868 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3869 {
3870 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3871 operands[3] = pic_offset_table_rtx;
3872 }
3873 [(set_attr "got" "xgot_high")])
3874
3875 (define_insn_and_split "*xgot_losi"
3876 [(set (match_operand:SI 0 "register_operand" "=d")
3877 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
3878 (match_operand:SI 2 "global_got_operand" "")))]
3879 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3880 "#"
3881 "&& reload_completed"
3882 [(set (match_dup 0)
3883 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3884 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3885 [(set_attr "got" "load")])
3886
3887 (define_insn_and_split "*xgot_hidi"
3888 [(set (match_operand:DI 0 "register_operand" "=d")
3889 (high:DI (match_operand:DI 1 "global_got_operand" "")))]
3890 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3891 "#"
3892 "&& reload_completed"
3893 [(set (match_dup 0) (high:DI (match_dup 2)))
3894 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3895 {
3896 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3897 operands[3] = pic_offset_table_rtx;
3898 }
3899 [(set_attr "got" "xgot_high")])
3900
3901 (define_insn_and_split "*xgot_lodi"
3902 [(set (match_operand:DI 0 "register_operand" "=d")
3903 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
3904 (match_operand:DI 2 "global_got_operand" "")))]
3905 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3906 "#"
3907 "&& reload_completed"
3908 [(set (match_dup 0)
3909 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3910 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3911 [(set_attr "got" "load")])
3912
3913 ;; Insns to fetch a global symbol from a normal GOT.
3914
3915 (define_insn_and_split "*got_dispsi"
3916 [(set (match_operand:SI 0 "register_operand" "=d")
3917 (match_operand:SI 1 "global_got_operand" ""))]
3918 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3919 "#"
3920 "&& reload_completed"
3921 [(set (match_dup 0)
3922 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3923 {
3924 operands[2] = pic_offset_table_rtx;
3925 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3926 }
3927 [(set_attr "got" "load")])
3928
3929 (define_insn_and_split "*got_dispdi"
3930 [(set (match_operand:DI 0 "register_operand" "=d")
3931 (match_operand:DI 1 "global_got_operand" ""))]
3932 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3933 "#"
3934 "&& reload_completed"
3935 [(set (match_dup 0)
3936 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3937 {
3938 operands[2] = pic_offset_table_rtx;
3939 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3940 }
3941 [(set_attr "got" "load")])
3942
3943 ;; Insns for loading the high part of a local symbol.
3944
3945 (define_insn_and_split "*got_pagesi"
3946 [(set (match_operand:SI 0 "register_operand" "=d")
3947 (high:SI (match_operand:SI 1 "local_got_operand" "")))]
3948 "TARGET_EXPLICIT_RELOCS"
3949 "#"
3950 "&& reload_completed"
3951 [(set (match_dup 0)
3952 (unspec:SI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3953 {
3954 operands[2] = pic_offset_table_rtx;
3955 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3956 }
3957 [(set_attr "got" "load")])
3958
3959 (define_insn_and_split "*got_pagedi"
3960 [(set (match_operand:DI 0 "register_operand" "=d")
3961 (high:DI (match_operand:DI 1 "local_got_operand" "")))]
3962 "TARGET_EXPLICIT_RELOCS"
3963 "#"
3964 "&& reload_completed"
3965 [(set (match_dup 0)
3966 (unspec:DI [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3967 {
3968 operands[2] = pic_offset_table_rtx;
3969 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3970 }
3971 [(set_attr "got" "load")])
3972
3973 ;; Lower-level instructions for loading an address from the GOT.
3974 ;; We could use MEMs, but an unspec gives more optimization
3975 ;; opportunities.
3976
3977 (define_insn "*load_gotsi"
3978 [(set (match_operand:SI 0 "register_operand" "=d")
3979 (unspec:SI [(match_operand:SI 1 "register_operand" "d")
3980 (match_operand:SI 2 "immediate_operand" "")]
3981 UNSPEC_LOAD_GOT))]
3982 "TARGET_ABICALLS"
3983 "lw\t%0,%R2(%1)"
3984 [(set_attr "type" "load")
3985 (set_attr "length" "4")])
3986
3987 (define_insn "*load_gotdi"
3988 [(set (match_operand:DI 0 "register_operand" "=d")
3989 (unspec:DI [(match_operand:DI 1 "register_operand" "d")
3990 (match_operand:DI 2 "immediate_operand" "")]
3991 UNSPEC_LOAD_GOT))]
3992 "TARGET_ABICALLS"
3993 "ld\t%0,%R2(%1)"
3994 [(set_attr "type" "load")
3995 (set_attr "length" "4")])
3996
3997 ;; Instructions for adding the low 16 bits of an address to a register.
3998 ;; Operand 2 is the address: print_operand works out which relocation
3999 ;; should be applied.
4000
4001 (define_insn "*lowsi"
4002 [(set (match_operand:SI 0 "register_operand" "=d")
4003 (lo_sum:SI (match_operand:SI 1 "register_operand" "d")
4004 (match_operand:SI 2 "immediate_operand" "")))]
4005 "!TARGET_MIPS16"
4006 "addiu\t%0,%1,%R2"
4007 [(set_attr "type" "arith")
4008 (set_attr "mode" "SI")])
4009
4010 (define_insn "*lowdi"
4011 [(set (match_operand:DI 0 "register_operand" "=d")
4012 (lo_sum:DI (match_operand:DI 1 "register_operand" "d")
4013 (match_operand:DI 2 "immediate_operand" "")))]
4014 "!TARGET_MIPS16 && TARGET_64BIT"
4015 "daddiu\t%0,%1,%R2"
4016 [(set_attr "type" "arith")
4017 (set_attr "mode" "DI")])
4018
4019 (define_insn "*lowsi_mips16"
4020 [(set (match_operand:SI 0 "register_operand" "=d")
4021 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4022 (match_operand:SI 2 "immediate_operand" "")))]
4023 "TARGET_MIPS16"
4024 "addiu\t%0,%R2"
4025 [(set_attr "type" "arith")
4026 (set_attr "mode" "SI")
4027 (set_attr "length" "8")])
4028
4029 (define_insn "*lowdi_mips16"
4030 [(set (match_operand:DI 0 "register_operand" "=d")
4031 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4032 (match_operand:DI 2 "immediate_operand" "")))]
4033 "TARGET_MIPS16 && TARGET_64BIT"
4034 "daddiu\t%0,%R2"
4035 [(set_attr "type" "arith")
4036 (set_attr "mode" "DI")
4037 (set_attr "length" "8")])
4038
4039 ;; 64-bit integer moves
4040
4041 ;; Unlike most other insns, the move insns can't be split with
4042 ;; different predicates, because register spilling and other parts of
4043 ;; the compiler, have memoized the insn number already.
4044
4045 (define_expand "movdi"
4046 [(set (match_operand:DI 0 "")
4047 (match_operand:DI 1 ""))]
4048 ""
4049 {
4050 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4051 DONE;
4052 })
4053
4054 ;; For mips16, we need a special case to handle storing $31 into
4055 ;; memory, since we don't have a constraint to match $31. This
4056 ;; instruction can be generated by save_restore_insns.
4057
4058 (define_insn ""
4059 [(set (match_operand:DI 0 "stack_operand" "=m")
4060 (reg:DI 31))]
4061 "TARGET_MIPS16 && TARGET_64BIT"
4062 "sd\t$31,%0"
4063 [(set_attr "type" "store")
4064 (set_attr "mode" "DI")])
4065
4066 (define_insn "*movdi_32bit"
4067 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
4068 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
4069 "!TARGET_64BIT && !TARGET_MIPS16
4070 && (register_operand (operands[0], DImode)
4071 || reg_or_0_operand (operands[1], DImode))"
4072 { return mips_output_move (operands[0], operands[1]); }
4073 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
4074 (set_attr "mode" "DI")
4075 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
4076
4077 (define_insn "*movdi_32bit_mips16"
4078 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4079 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
4080 "!TARGET_64BIT && TARGET_MIPS16
4081 && (register_operand (operands[0], DImode)
4082 || register_operand (operands[1], DImode))"
4083 { return mips_output_move (operands[0], operands[1]); }
4084 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
4085 (set_attr "mode" "DI")
4086 (set_attr "length" "8,8,8,8,12,*,*,8")])
4087
4088 (define_insn "*movdi_64bit"
4089 [(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")
4090 (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"))]
4091 "TARGET_64BIT && !TARGET_MIPS16
4092 && (register_operand (operands[0], DImode)
4093 || reg_or_0_operand (operands[1], DImode))"
4094 { return mips_output_move (operands[0], operands[1]); }
4095 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
4096 (set_attr "mode" "DI")
4097 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
4098
4099 (define_insn "*movdi_64bit_mips16"
4100 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4101 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4102 "TARGET_64BIT && TARGET_MIPS16
4103 && (register_operand (operands[0], DImode)
4104 || register_operand (operands[1], DImode))"
4105 { return mips_output_move (operands[0], operands[1]); }
4106 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4107 (set_attr "mode" "DI")
4108 (set_attr_alternative "length"
4109 [(const_int 4)
4110 (const_int 4)
4111 (const_int 4)
4112 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4113 (const_int 4)
4114 (const_int 8))
4115 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4116 (const_int 8)
4117 (const_int 12))
4118 (const_string "*")
4119 (const_string "*")
4120 (const_string "*")])])
4121
4122
4123 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4124 ;; when the original load is a 4 byte instruction but the add and the
4125 ;; load are 2 2 byte instructions.
4126
4127 (define_split
4128 [(set (match_operand:DI 0 "register_operand")
4129 (mem:DI (plus:DI (match_dup 0)
4130 (match_operand:DI 1 "const_int_operand"))))]
4131 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4132 && !TARGET_DEBUG_D_MODE
4133 && GET_CODE (operands[0]) == REG
4134 && M16_REG_P (REGNO (operands[0]))
4135 && GET_CODE (operands[1]) == CONST_INT
4136 && ((INTVAL (operands[1]) < 0
4137 && INTVAL (operands[1]) >= -0x10)
4138 || (INTVAL (operands[1]) >= 32 * 8
4139 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4140 || (INTVAL (operands[1]) >= 0
4141 && INTVAL (operands[1]) < 32 * 8
4142 && (INTVAL (operands[1]) & 7) != 0))"
4143 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4144 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4145 {
4146 HOST_WIDE_INT val = INTVAL (operands[1]);
4147
4148 if (val < 0)
4149 operands[2] = const0_rtx;
4150 else if (val >= 32 * 8)
4151 {
4152 int off = val & 7;
4153
4154 operands[1] = GEN_INT (0x8 + off);
4155 operands[2] = GEN_INT (val - off - 0x8);
4156 }
4157 else
4158 {
4159 int off = val & 7;
4160
4161 operands[1] = GEN_INT (off);
4162 operands[2] = GEN_INT (val - off);
4163 }
4164 })
4165
4166 ;; 32-bit Integer moves
4167
4168 ;; Unlike most other insns, the move insns can't be split with
4169 ;; different predicates, because register spilling and other parts of
4170 ;; the compiler, have memoized the insn number already.
4171
4172 (define_expand "movsi"
4173 [(set (match_operand:SI 0 "")
4174 (match_operand:SI 1 ""))]
4175 ""
4176 {
4177 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4178 DONE;
4179 })
4180
4181 ;; We can only store $ra directly into a small sp offset.
4182
4183 (define_insn ""
4184 [(set (match_operand:SI 0 "stack_operand" "=m")
4185 (reg:SI 31))]
4186 "TARGET_MIPS16"
4187 "sw\t$31,%0"
4188 [(set_attr "type" "store")
4189 (set_attr "mode" "SI")])
4190
4191 ;; The difference between these two is whether or not ints are allowed
4192 ;; in FP registers (off by default, use -mdebugh to enable).
4193
4194 (define_insn "*movsi_internal"
4195 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
4196 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
4197 "!TARGET_MIPS16
4198 && (register_operand (operands[0], SImode)
4199 || reg_or_0_operand (operands[1], SImode))"
4200 { return mips_output_move (operands[0], operands[1]); }
4201 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
4202 (set_attr "mode" "SI")
4203 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
4204
4205 (define_insn "*movsi_mips16"
4206 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
4207 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
4208 "TARGET_MIPS16
4209 && (register_operand (operands[0], SImode)
4210 || register_operand (operands[1], SImode))"
4211 { return mips_output_move (operands[0], operands[1]); }
4212 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
4213 (set_attr "mode" "SI")
4214 (set_attr_alternative "length"
4215 [(const_int 4)
4216 (const_int 4)
4217 (const_int 4)
4218 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4219 (const_int 4)
4220 (const_int 8))
4221 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4222 (const_int 8)
4223 (const_int 12))
4224 (const_string "*")
4225 (const_string "*")
4226 (const_string "*")])])
4227
4228 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4229 ;; when the original load is a 4 byte instruction but the add and the
4230 ;; load are 2 2 byte instructions.
4231
4232 (define_split
4233 [(set (match_operand:SI 0 "register_operand")
4234 (mem:SI (plus:SI (match_dup 0)
4235 (match_operand:SI 1 "const_int_operand"))))]
4236 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4237 && GET_CODE (operands[0]) == REG
4238 && M16_REG_P (REGNO (operands[0]))
4239 && GET_CODE (operands[1]) == CONST_INT
4240 && ((INTVAL (operands[1]) < 0
4241 && INTVAL (operands[1]) >= -0x80)
4242 || (INTVAL (operands[1]) >= 32 * 4
4243 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4244 || (INTVAL (operands[1]) >= 0
4245 && INTVAL (operands[1]) < 32 * 4
4246 && (INTVAL (operands[1]) & 3) != 0))"
4247 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4248 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4249 {
4250 HOST_WIDE_INT val = INTVAL (operands[1]);
4251
4252 if (val < 0)
4253 operands[2] = const0_rtx;
4254 else if (val >= 32 * 4)
4255 {
4256 int off = val & 3;
4257
4258 operands[1] = GEN_INT (0x7c + off);
4259 operands[2] = GEN_INT (val - off - 0x7c);
4260 }
4261 else
4262 {
4263 int off = val & 3;
4264
4265 operands[1] = GEN_INT (off);
4266 operands[2] = GEN_INT (val - off);
4267 }
4268 })
4269
4270 ;; On the mips16, we can split a load of certain constants into a load
4271 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4272 ;; instructions.
4273
4274 (define_split
4275 [(set (match_operand:SI 0 "register_operand")
4276 (match_operand:SI 1 "const_int_operand"))]
4277 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4278 && GET_CODE (operands[0]) == REG
4279 && M16_REG_P (REGNO (operands[0]))
4280 && GET_CODE (operands[1]) == CONST_INT
4281 && INTVAL (operands[1]) >= 0x100
4282 && INTVAL (operands[1]) <= 0xff + 0x7f"
4283 [(set (match_dup 0) (match_dup 1))
4284 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4285 {
4286 int val = INTVAL (operands[1]);
4287
4288 operands[1] = GEN_INT (0xff);
4289 operands[2] = GEN_INT (val - 0xff);
4290 })
4291
4292 ;; This insn handles moving CCmode values. It's really just a
4293 ;; slightly simplified copy of movsi_internal2, with additional cases
4294 ;; to move a condition register to a general register and to move
4295 ;; between the general registers and the floating point registers.
4296
4297 (define_insn "movcc"
4298 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4299 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4300 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4301 { return mips_output_move (operands[0], operands[1]); }
4302 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore")
4303 (set_attr "mode" "SI")
4304 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4305
4306 ;; Reload condition code registers. reload_incc and reload_outcc
4307 ;; both handle moves from arbitrary operands into condition code
4308 ;; registers. reload_incc handles the more common case in which
4309 ;; a source operand is constrained to be in a condition-code
4310 ;; register, but has not been allocated to one.
4311 ;;
4312 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4313 ;; constraints do not include 'z'. reload_outcc handles the case
4314 ;; when such an operand is allocated to a condition-code register.
4315 ;;
4316 ;; Note that reloads from a condition code register to some
4317 ;; other location can be done using ordinary moves. Moving
4318 ;; into a GPR takes a single movcc, moving elsewhere takes
4319 ;; two. We can leave these cases to the generic reload code.
4320 (define_expand "reload_incc"
4321 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4322 (match_operand:CC 1 "general_operand" ""))
4323 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4324 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4325 {
4326 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4327 DONE;
4328 })
4329
4330 (define_expand "reload_outcc"
4331 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4332 (match_operand:CC 1 "register_operand" ""))
4333 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4334 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4335 {
4336 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4337 DONE;
4338 })
4339
4340 ;; MIPS4 supports loading and storing a floating point register from
4341 ;; the sum of two general registers. We use two versions for each of
4342 ;; these four instructions: one where the two general registers are
4343 ;; SImode, and one where they are DImode. This is because general
4344 ;; registers will be in SImode when they hold 32 bit values, but,
4345 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4346 ;; instructions will still work correctly.
4347
4348 ;; ??? Perhaps it would be better to support these instructions by
4349 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4350 ;; these instructions can only be used to load and store floating
4351 ;; point registers, that would probably cause trouble in reload.
4352
4353 (define_insn ""
4354 [(set (match_operand:SF 0 "register_operand" "=f")
4355 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4356 (match_operand:SI 2 "register_operand" "d"))))]
4357 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4358 "lwxc1\t%0,%1(%2)"
4359 [(set_attr "type" "fpidxload")
4360 (set_attr "mode" "SF")
4361 (set_attr "length" "4")])
4362
4363 (define_insn ""
4364 [(set (match_operand:SF 0 "register_operand" "=f")
4365 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4366 (match_operand:DI 2 "register_operand" "d"))))]
4367 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4368 "lwxc1\t%0,%1(%2)"
4369 [(set_attr "type" "fpidxload")
4370 (set_attr "mode" "SF")
4371 (set_attr "length" "4")])
4372
4373 (define_insn ""
4374 [(set (match_operand:DF 0 "register_operand" "=f")
4375 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4376 (match_operand:SI 2 "register_operand" "d"))))]
4377 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4378 "ldxc1\t%0,%1(%2)"
4379 [(set_attr "type" "fpidxload")
4380 (set_attr "mode" "DF")
4381 (set_attr "length" "4")])
4382
4383 (define_insn ""
4384 [(set (match_operand:DF 0 "register_operand" "=f")
4385 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4386 (match_operand:DI 2 "register_operand" "d"))))]
4387 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4388 "ldxc1\t%0,%1(%2)"
4389 [(set_attr "type" "fpidxload")
4390 (set_attr "mode" "DF")
4391 (set_attr "length" "4")])
4392
4393 (define_insn ""
4394 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4395 (match_operand:SI 2 "register_operand" "d")))
4396 (match_operand:SF 0 "register_operand" "f"))]
4397 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4398 "swxc1\t%0,%1(%2)"
4399 [(set_attr "type" "fpidxstore")
4400 (set_attr "mode" "SF")
4401 (set_attr "length" "4")])
4402
4403 (define_insn ""
4404 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4405 (match_operand:DI 2 "register_operand" "d")))
4406 (match_operand:SF 0 "register_operand" "f"))]
4407 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4408 "swxc1\t%0,%1(%2)"
4409 [(set_attr "type" "fpidxstore")
4410 (set_attr "mode" "SF")
4411 (set_attr "length" "4")])
4412
4413 (define_insn ""
4414 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4415 (match_operand:SI 2 "register_operand" "d")))
4416 (match_operand:DF 0 "register_operand" "f"))]
4417 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4418 "sdxc1\t%0,%1(%2)"
4419 [(set_attr "type" "fpidxstore")
4420 (set_attr "mode" "DF")
4421 (set_attr "length" "4")])
4422
4423 (define_insn ""
4424 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4425 (match_operand:DI 2 "register_operand" "d")))
4426 (match_operand:DF 0 "register_operand" "f"))]
4427 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4428 "sdxc1\t%0,%1(%2)"
4429 [(set_attr "type" "fpidxstore")
4430 (set_attr "mode" "DF")
4431 (set_attr "length" "4")])
4432
4433 ;; 16-bit Integer moves
4434
4435 ;; Unlike most other insns, the move insns can't be split with
4436 ;; different predicates, because register spilling and other parts of
4437 ;; the compiler, have memoized the insn number already.
4438 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4439
4440 (define_expand "movhi"
4441 [(set (match_operand:HI 0 "")
4442 (match_operand:HI 1 ""))]
4443 ""
4444 {
4445 if (mips_legitimize_move (HImode, operands[0], operands[1]))
4446 DONE;
4447 })
4448
4449 (define_insn "*movhi_internal"
4450 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4451 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4452 "!TARGET_MIPS16
4453 && (register_operand (operands[0], HImode)
4454 || reg_or_0_operand (operands[1], HImode))"
4455 "@
4456 move\t%0,%1
4457 li\t%0,%1
4458 lhu\t%0,%1
4459 sh\t%z1,%0
4460 mfc1\t%0,%1
4461 mtc1\t%1,%0
4462 mov.s\t%0,%1
4463 mt%0\t%1"
4464 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4465 (set_attr "mode" "HI")
4466 (set_attr "length" "4,4,*,*,4,4,4,4")])
4467
4468 (define_insn "*movhi_mips16"
4469 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4470 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
4471 "TARGET_MIPS16
4472 && (register_operand (operands[0], HImode)
4473 || register_operand (operands[1], HImode))"
4474 "@
4475 move\t%0,%1
4476 move\t%0,%1
4477 move\t%0,%1
4478 li\t%0,%1
4479 #
4480 lhu\t%0,%1
4481 sh\t%1,%0"
4482 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4483 (set_attr "mode" "HI")
4484 (set_attr_alternative "length"
4485 [(const_int 4)
4486 (const_int 4)
4487 (const_int 4)
4488 (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
4489 (const_int 4)
4490 (const_int 8))
4491 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
4492 (const_int 8)
4493 (const_int 12))
4494 (const_string "*")
4495 (const_string "*")])])
4496
4497
4498 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4499 ;; when the original load is a 4 byte instruction but the add and the
4500 ;; load are 2 2 byte instructions.
4501
4502 (define_split
4503 [(set (match_operand:HI 0 "register_operand")
4504 (mem:HI (plus:SI (match_dup 0)
4505 (match_operand:SI 1 "const_int_operand"))))]
4506 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4507 && GET_CODE (operands[0]) == REG
4508 && M16_REG_P (REGNO (operands[0]))
4509 && GET_CODE (operands[1]) == CONST_INT
4510 && ((INTVAL (operands[1]) < 0
4511 && INTVAL (operands[1]) >= -0x80)
4512 || (INTVAL (operands[1]) >= 32 * 2
4513 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4514 || (INTVAL (operands[1]) >= 0
4515 && INTVAL (operands[1]) < 32 * 2
4516 && (INTVAL (operands[1]) & 1) != 0))"
4517 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4518 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4519 {
4520 HOST_WIDE_INT val = INTVAL (operands[1]);
4521
4522 if (val < 0)
4523 operands[2] = const0_rtx;
4524 else if (val >= 32 * 2)
4525 {
4526 int off = val & 1;
4527
4528 operands[1] = GEN_INT (0x7e + off);
4529 operands[2] = GEN_INT (val - off - 0x7e);
4530 }
4531 else
4532 {
4533 int off = val & 1;
4534
4535 operands[1] = GEN_INT (off);
4536 operands[2] = GEN_INT (val - off);
4537 }
4538 })
4539
4540 ;; 8-bit Integer moves
4541
4542 ;; Unlike most other insns, the move insns can't be split with
4543 ;; different predicates, because register spilling and other parts of
4544 ;; the compiler, have memoized the insn number already.
4545 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4546
4547 (define_expand "movqi"
4548 [(set (match_operand:QI 0 "")
4549 (match_operand:QI 1 ""))]
4550 ""
4551 {
4552 if (mips_legitimize_move (QImode, operands[0], operands[1]))
4553 DONE;
4554 })
4555
4556 (define_insn "*movqi_internal"
4557 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
4558 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
4559 "!TARGET_MIPS16
4560 && (register_operand (operands[0], QImode)
4561 || reg_or_0_operand (operands[1], QImode))"
4562 "@
4563 move\t%0,%1
4564 li\t%0,%1
4565 lbu\t%0,%1
4566 sb\t%z1,%0
4567 mfc1\t%0,%1
4568 mtc1\t%1,%0
4569 mov.s\t%0,%1
4570 mt%0\t%1"
4571 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
4572 (set_attr "mode" "QI")
4573 (set_attr "length" "4,4,*,*,4,4,4,4")])
4574
4575 (define_insn "*movqi_mips16"
4576 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
4577 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
4578 "TARGET_MIPS16
4579 && (register_operand (operands[0], QImode)
4580 || register_operand (operands[1], QImode))"
4581 "@
4582 move\t%0,%1
4583 move\t%0,%1
4584 move\t%0,%1
4585 li\t%0,%1
4586 #
4587 lbu\t%0,%1
4588 sb\t%1,%0"
4589 [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
4590 (set_attr "mode" "QI")
4591 (set_attr "length" "4,4,4,4,8,*,*")])
4592
4593 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4594 ;; when the original load is a 4 byte instruction but the add and the
4595 ;; load are 2 2 byte instructions.
4596
4597 (define_split
4598 [(set (match_operand:QI 0 "register_operand")
4599 (mem:QI (plus:SI (match_dup 0)
4600 (match_operand:SI 1 "const_int_operand"))))]
4601 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4602 && GET_CODE (operands[0]) == REG
4603 && M16_REG_P (REGNO (operands[0]))
4604 && GET_CODE (operands[1]) == CONST_INT
4605 && ((INTVAL (operands[1]) < 0
4606 && INTVAL (operands[1]) >= -0x80)
4607 || (INTVAL (operands[1]) >= 32
4608 && INTVAL (operands[1]) <= 31 + 0x7f))"
4609 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4610 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4611 {
4612 HOST_WIDE_INT val = INTVAL (operands[1]);
4613
4614 if (val < 0)
4615 operands[2] = const0_rtx;
4616 else
4617 {
4618 operands[1] = GEN_INT (0x7f);
4619 operands[2] = GEN_INT (val - 0x7f);
4620 }
4621 })
4622
4623 ;; 32-bit floating point moves
4624
4625 (define_expand "movsf"
4626 [(set (match_operand:SF 0 "")
4627 (match_operand:SF 1 ""))]
4628 ""
4629 {
4630 if (mips_legitimize_move (SFmode, operands[0], operands[1]))
4631 DONE;
4632 })
4633
4634 (define_insn "*movsf_hardfloat"
4635 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4636 (match_operand:SF 1 "move_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4637 "TARGET_HARD_FLOAT
4638 && (register_operand (operands[0], SFmode)
4639 || reg_or_0_operand (operands[1], SFmode))"
4640 { return mips_output_move (operands[0], operands[1]); }
4641 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4642 (set_attr "mode" "SF")
4643 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4644
4645 (define_insn "*movsf_softfloat"
4646 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4647 (match_operand:SF 1 "move_operand" "Gd,m,d"))]
4648 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4649 && (register_operand (operands[0], SFmode)
4650 || reg_or_0_operand (operands[1], SFmode))"
4651 { return mips_output_move (operands[0], operands[1]); }
4652 [(set_attr "type" "arith,load,store")
4653 (set_attr "mode" "SF")
4654 (set_attr "length" "4,*,*")])
4655
4656 (define_insn "*movsf_mips16"
4657 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4658 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))]
4659 "TARGET_MIPS16
4660 && (register_operand (operands[0], SFmode)
4661 || register_operand (operands[1], SFmode))"
4662 { return mips_output_move (operands[0], operands[1]); }
4663 [(set_attr "type" "arith,arith,arith,load,store")
4664 (set_attr "mode" "SF")
4665 (set_attr "length" "4,4,4,*,*")])
4666
4667
4668 ;; 64-bit floating point moves
4669
4670 (define_expand "movdf"
4671 [(set (match_operand:DF 0 "")
4672 (match_operand:DF 1 ""))]
4673 ""
4674 {
4675 if (mips_legitimize_move (DFmode, operands[0], operands[1]))
4676 DONE;
4677 })
4678
4679 (define_insn "*movdf_hardfloat_64bit"
4680 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4681 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4682 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4683 && (register_operand (operands[0], DFmode)
4684 || reg_or_0_operand (operands[1], DFmode))"
4685 { return mips_output_move (operands[0], operands[1]); }
4686 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4687 (set_attr "mode" "DF")
4688 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4689
4690 (define_insn "*movdf_hardfloat_32bit"
4691 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4692 (match_operand:DF 1 "move_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4693 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4694 && (register_operand (operands[0], DFmode)
4695 || reg_or_0_operand (operands[1], DFmode))"
4696 { return mips_output_move (operands[0], operands[1]); }
4697 [(set_attr "type" "fmove,xfer,fpload,fpstore,xfer,xfer,arith,load,store")
4698 (set_attr "mode" "DF")
4699 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4700
4701 (define_insn "*movdf_softfloat"
4702 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4703 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))]
4704 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4705 && (register_operand (operands[0], DFmode)
4706 || reg_or_0_operand (operands[1], DFmode))"
4707 { return mips_output_move (operands[0], operands[1]); }
4708 [(set_attr "type" "arith,load,store,xfer,xfer,fmove")
4709 (set_attr "mode" "DF")
4710 (set_attr "length" "8,*,*,4,4,4")])
4711
4712 (define_insn "*movdf_mips16"
4713 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4714 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))]
4715 "TARGET_MIPS16
4716 && (register_operand (operands[0], DFmode)
4717 || register_operand (operands[1], DFmode))"
4718 { return mips_output_move (operands[0], operands[1]); }
4719 [(set_attr "type" "arith,arith,arith,load,store")
4720 (set_attr "mode" "DF")
4721 (set_attr "length" "8,8,8,*,*")])
4722
4723 (define_split
4724 [(set (match_operand:DI 0 "nonimmediate_operand")
4725 (match_operand:DI 1 "move_operand"))]
4726 "reload_completed && !TARGET_64BIT
4727 && mips_split_64bit_move_p (operands[0], operands[1])"
4728 [(const_int 0)]
4729 {
4730 mips_split_64bit_move (operands[0], operands[1]);
4731 DONE;
4732 })
4733
4734 (define_split
4735 [(set (match_operand:DF 0 "nonimmediate_operand")
4736 (match_operand:DF 1 "move_operand"))]
4737 "reload_completed && !TARGET_64BIT
4738 && mips_split_64bit_move_p (operands[0], operands[1])"
4739 [(const_int 0)]
4740 {
4741 mips_split_64bit_move (operands[0], operands[1]);
4742 DONE;
4743 })
4744
4745 ;; When generating mips16 code, split moves of negative constants into
4746 ;; a positive "li" followed by a negation.
4747 (define_split
4748 [(set (match_operand 0 "register_operand")
4749 (match_operand 1 "const_int_operand"))]
4750 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
4751 [(set (match_dup 2)
4752 (match_dup 3))
4753 (set (match_dup 2)
4754 (neg:SI (match_dup 2)))]
4755 {
4756 operands[2] = gen_lowpart (SImode, operands[0]);
4757 operands[3] = GEN_INT (-INTVAL (operands[1]));
4758 })
4759
4760 ;; The HI and LO registers are not truly independent. If we move an mthi
4761 ;; instruction before an mflo instruction, it will make the result of the
4762 ;; mflo unpredictable. The same goes for mtlo and mfhi.
4763 ;;
4764 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
4765 ;; Operand 1 is the register we want, operand 2 is the other one.
4766
4767 (define_insn "mfhilo_di"
4768 [(set (match_operand:DI 0 "register_operand" "=d,d")
4769 (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
4770 (match_operand:DI 2 "register_operand" "l,h")]
4771 UNSPEC_MFHILO))]
4772 "TARGET_64BIT"
4773 "mf%1\t%0"
4774 [(set_attr "type" "mfhilo")])
4775
4776 (define_insn "mfhilo_si"
4777 [(set (match_operand:SI 0 "register_operand" "=d,d")
4778 (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
4779 (match_operand:SI 2 "register_operand" "l,h")]
4780 UNSPEC_MFHILO))]
4781 ""
4782 "mf%1\t%0"
4783 [(set_attr "type" "mfhilo")])
4784
4785 ;; Patterns for loading or storing part of a paired floating point
4786 ;; register. We need them because odd-numbered floating-point registers
4787 ;; are not fully independent: see mips_split_64bit_move.
4788
4789 ;; Load the low word of operand 0 with operand 1.
4790 (define_insn "load_df_low"
4791 [(set (match_operand:DF 0 "register_operand" "=f,f")
4792 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
4793 UNSPEC_LOAD_DF_LOW))]
4794 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4795 {
4796 operands[0] = mips_subword (operands[0], 0);
4797 return mips_output_move (operands[0], operands[1]);
4798 }
4799 [(set_attr "type" "xfer,fpload")
4800 (set_attr "mode" "SF")])
4801
4802 ;; Load the high word of operand 0 from operand 1, preserving the value
4803 ;; in the low word.
4804 (define_insn "load_df_high"
4805 [(set (match_operand:DF 0 "register_operand" "=f,f")
4806 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
4807 (match_operand:DF 2 "register_operand" "0,0")]
4808 UNSPEC_LOAD_DF_HIGH))]
4809 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4810 {
4811 operands[0] = mips_subword (operands[0], 1);
4812 return mips_output_move (operands[0], operands[1]);
4813 }
4814 [(set_attr "type" "xfer,fpload")
4815 (set_attr "mode" "SF")])
4816
4817 ;; Store the high word of operand 1 in operand 0. The corresponding
4818 ;; low-word move is done in the normal way.
4819 (define_insn "store_df_high"
4820 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
4821 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
4822 UNSPEC_STORE_DF_HIGH))]
4823 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
4824 {
4825 operands[1] = mips_subword (operands[1], 1);
4826 return mips_output_move (operands[0], operands[1]);
4827 }
4828 [(set_attr "type" "xfer,fpstore")
4829 (set_attr "mode" "SF")])
4830
4831 ;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
4832 ;; of _gp from the start of this function. Operand 1 is the incoming
4833 ;; function address.
4834 (define_insn_and_split "loadgp"
4835 [(unspec_volatile [(match_operand 0 "" "")
4836 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
4837 "TARGET_ABICALLS && TARGET_NEWABI"
4838 "#"
4839 ""
4840 [(set (match_dup 2) (match_dup 3))
4841 (set (match_dup 2) (match_dup 4))
4842 (set (match_dup 2) (match_dup 5))]
4843 {
4844 operands[2] = pic_offset_table_rtx;
4845 operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
4846 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
4847 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
4848 }
4849 [(set_attr "length" "12")])
4850
4851 ;; The use of gp is hidden when not using explicit relocations.
4852 ;; This blockage instruction prevents the gp load from being
4853 ;; scheduled after an implicit use of gp. It also prevents
4854 ;; the load from being deleted as dead.
4855 (define_insn "loadgp_blockage"
4856 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
4857 ""
4858 ""
4859 [(set_attr "type" "unknown")
4860 (set_attr "mode" "none")
4861 (set_attr "length" "0")])
4862
4863 ;; Emit a .cprestore directive, which expands to a single store instruction.
4864 ;; Note that we continue to use .cprestore for explicit reloc code so that
4865 ;; jals inside inlines asms will work correctly.
4866 (define_insn "cprestore"
4867 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
4868 UNSPEC_CPRESTORE)]
4869 ""
4870 ".cprestore\t%0"
4871 [(set_attr "type" "store")
4872 (set_attr "length" "4")])
4873 \f
4874 ;; Block moves, see mips.c for more details.
4875 ;; Argument 0 is the destination
4876 ;; Argument 1 is the source
4877 ;; Argument 2 is the length
4878 ;; Argument 3 is the alignment
4879
4880 (define_expand "movmemsi"
4881 [(parallel [(set (match_operand:BLK 0 "general_operand")
4882 (match_operand:BLK 1 "general_operand"))
4883 (use (match_operand:SI 2 ""))
4884 (use (match_operand:SI 3 "const_int_operand"))])]
4885 "!TARGET_MIPS16 && !TARGET_MEMCPY"
4886 {
4887 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
4888 DONE;
4889 else
4890 FAIL;
4891 })
4892 \f
4893 ;;
4894 ;; ....................
4895 ;;
4896 ;; SHIFTS
4897 ;;
4898 ;; ....................
4899
4900 ;; Many of these instructions use trivial define_expands, because we
4901 ;; want to use a different set of constraints when TARGET_MIPS16.
4902
4903 (define_expand "ashlsi3"
4904 [(set (match_operand:SI 0 "register_operand")
4905 (ashift:SI (match_operand:SI 1 "register_operand")
4906 (match_operand:SI 2 "arith_operand")))]
4907 ""
4908 {
4909 /* On the mips16, a shift of more than 8 is a four byte instruction,
4910 so, for a shift between 8 and 16, it is just as fast to do two
4911 shifts of 8 or less. If there is a lot of shifting going on, we
4912 may win in CSE. Otherwise combine will put the shifts back
4913 together again. This can be called by function_arg, so we must
4914 be careful not to allocate a new register if we've reached the
4915 reload pass. */
4916 if (TARGET_MIPS16
4917 && optimize
4918 && GET_CODE (operands[2]) == CONST_INT
4919 && INTVAL (operands[2]) > 8
4920 && INTVAL (operands[2]) <= 16
4921 && ! reload_in_progress
4922 && ! reload_completed)
4923 {
4924 rtx temp = gen_reg_rtx (SImode);
4925
4926 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
4927 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
4928 GEN_INT (INTVAL (operands[2]) - 8)));
4929 DONE;
4930 }
4931 })
4932
4933 (define_insn "ashlsi3_internal1"
4934 [(set (match_operand:SI 0 "register_operand" "=d")
4935 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4936 (match_operand:SI 2 "arith_operand" "dI")))]
4937 "!TARGET_MIPS16"
4938 {
4939 if (GET_CODE (operands[2]) == CONST_INT)
4940 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4941
4942 return "sll\t%0,%1,%2";
4943 }
4944 [(set_attr "type" "shift")
4945 (set_attr "mode" "SI")])
4946
4947 (define_insn "ashlsi3_internal1_extend"
4948 [(set (match_operand:DI 0 "register_operand" "=d")
4949 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
4950 (match_operand:SI 2 "arith_operand" "dI"))))]
4951 "TARGET_64BIT && !TARGET_MIPS16"
4952 {
4953 if (GET_CODE (operands[2]) == CONST_INT)
4954 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4955
4956 return "sll\t%0,%1,%2";
4957 }
4958 [(set_attr "type" "shift")
4959 (set_attr "mode" "DI")])
4960
4961
4962 (define_insn "ashlsi3_internal2"
4963 [(set (match_operand:SI 0 "register_operand" "=d,d")
4964 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
4965 (match_operand:SI 2 "arith_operand" "d,I")))]
4966 "TARGET_MIPS16"
4967 {
4968 if (which_alternative == 0)
4969 return "sll\t%0,%2";
4970
4971 if (GET_CODE (operands[2]) == CONST_INT)
4972 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4973
4974 return "sll\t%0,%1,%2";
4975 }
4976 [(set_attr "type" "shift")
4977 (set_attr "mode" "SI")
4978 (set_attr_alternative "length"
4979 [(const_int 4)
4980 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
4981 (const_int 4)
4982 (const_int 8))])])
4983
4984 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
4985
4986 (define_split
4987 [(set (match_operand:SI 0 "register_operand")
4988 (ashift:SI (match_operand:SI 1 "register_operand")
4989 (match_operand:SI 2 "const_int_operand")))]
4990 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4991 && GET_CODE (operands[2]) == CONST_INT
4992 && INTVAL (operands[2]) > 8
4993 && INTVAL (operands[2]) <= 16"
4994 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
4995 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4996 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
4997
4998 (define_expand "ashldi3"
4999 [(set (match_operand:DI 0 "register_operand")
5000 (ashift:DI (match_operand:DI 1 "register_operand")
5001 (match_operand:SI 2 "arith_operand")))]
5002 "TARGET_64BIT"
5003 {
5004 /* On the mips16, a shift of more than 8 is a four byte
5005 instruction, so, for a shift between 8 and 16, it is just as
5006 fast to do two shifts of 8 or less. If there is a lot of
5007 shifting going on, we may win in CSE. Otherwise combine will
5008 put the shifts back together again. This can be called by
5009 function_arg, so we must be careful not to allocate a new
5010 register if we've reached the reload pass. */
5011 if (TARGET_MIPS16
5012 && optimize
5013 && GET_CODE (operands[2]) == CONST_INT
5014 && INTVAL (operands[2]) > 8
5015 && INTVAL (operands[2]) <= 16
5016 && ! reload_in_progress
5017 && ! reload_completed)
5018 {
5019 rtx temp = gen_reg_rtx (DImode);
5020
5021 emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
5022 emit_insn (gen_ashldi3_internal (operands[0], temp,
5023 GEN_INT (INTVAL (operands[2]) - 8)));
5024 DONE;
5025 }
5026 })
5027
5028
5029 (define_insn "ashldi3_internal"
5030 [(set (match_operand:DI 0 "register_operand" "=d")
5031 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5032 (match_operand:SI 2 "arith_operand" "dI")))]
5033 "TARGET_64BIT && !TARGET_MIPS16"
5034 {
5035 if (GET_CODE (operands[2]) == CONST_INT)
5036 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5037
5038 return "dsll\t%0,%1,%2";
5039 }
5040 [(set_attr "type" "shift")
5041 (set_attr "mode" "DI")])
5042
5043 (define_insn ""
5044 [(set (match_operand:DI 0 "register_operand" "=d,d")
5045 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5046 (match_operand:SI 2 "arith_operand" "d,I")))]
5047 "TARGET_64BIT && TARGET_MIPS16"
5048 {
5049 if (which_alternative == 0)
5050 return "dsll\t%0,%2";
5051
5052 if (GET_CODE (operands[2]) == CONST_INT)
5053 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5054
5055 return "dsll\t%0,%1,%2";
5056 }
5057 [(set_attr "type" "shift")
5058 (set_attr "mode" "DI")
5059 (set_attr_alternative "length"
5060 [(const_int 4)
5061 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5062 (const_int 4)
5063 (const_int 8))])])
5064
5065
5066 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5067
5068 (define_split
5069 [(set (match_operand:DI 0 "register_operand")
5070 (ashift:DI (match_operand:DI 1 "register_operand")
5071 (match_operand:SI 2 "const_int_operand")))]
5072 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5073 && reload_completed
5074 && GET_CODE (operands[2]) == CONST_INT
5075 && INTVAL (operands[2]) > 8
5076 && INTVAL (operands[2]) <= 16"
5077 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5078 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5079 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5080
5081 (define_expand "ashrsi3"
5082 [(set (match_operand:SI 0 "register_operand")
5083 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5084 (match_operand:SI 2 "arith_operand")))]
5085 ""
5086 {
5087 /* On the mips16, a shift of more than 8 is a four byte instruction,
5088 so, for a shift between 8 and 16, it is just as fast to do two
5089 shifts of 8 or less. If there is a lot of shifting going on, we
5090 may win in CSE. Otherwise combine will put the shifts back
5091 together again. */
5092 if (TARGET_MIPS16
5093 && optimize
5094 && GET_CODE (operands[2]) == CONST_INT
5095 && INTVAL (operands[2]) > 8
5096 && INTVAL (operands[2]) <= 16)
5097 {
5098 rtx temp = gen_reg_rtx (SImode);
5099
5100 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5101 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5102 GEN_INT (INTVAL (operands[2]) - 8)));
5103 DONE;
5104 }
5105 })
5106
5107 (define_insn "ashrsi3_internal1"
5108 [(set (match_operand:SI 0 "register_operand" "=d")
5109 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5110 (match_operand:SI 2 "arith_operand" "dI")))]
5111 "!TARGET_MIPS16"
5112 {
5113 if (GET_CODE (operands[2]) == CONST_INT)
5114 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5115
5116 return "sra\t%0,%1,%2";
5117 }
5118 [(set_attr "type" "shift")
5119 (set_attr "mode" "SI")])
5120
5121 (define_insn "ashrsi3_internal2"
5122 [(set (match_operand:SI 0 "register_operand" "=d,d")
5123 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5124 (match_operand:SI 2 "arith_operand" "d,I")))]
5125 "TARGET_MIPS16"
5126 {
5127 if (which_alternative == 0)
5128 return "sra\t%0,%2";
5129
5130 if (GET_CODE (operands[2]) == CONST_INT)
5131 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5132
5133 return "sra\t%0,%1,%2";
5134 }
5135 [(set_attr "type" "shift")
5136 (set_attr "mode" "SI")
5137 (set_attr_alternative "length"
5138 [(const_int 4)
5139 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5140 (const_int 4)
5141 (const_int 8))])])
5142
5143
5144 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5145
5146 (define_split
5147 [(set (match_operand:SI 0 "register_operand")
5148 (ashiftrt:SI (match_operand:SI 1 "register_operand")
5149 (match_operand:SI 2 "const_int_operand")))]
5150 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5151 && GET_CODE (operands[2]) == CONST_INT
5152 && INTVAL (operands[2]) > 8
5153 && INTVAL (operands[2]) <= 16"
5154 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5155 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5156 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5157
5158 (define_expand "ashrdi3"
5159 [(set (match_operand:DI 0 "register_operand")
5160 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5161 (match_operand:SI 2 "arith_operand")))]
5162 "TARGET_64BIT"
5163 {
5164 /* On the mips16, a shift of more than 8 is a four byte
5165 instruction, so, for a shift between 8 and 16, it is just as
5166 fast to do two shifts of 8 or less. If there is a lot of
5167 shifting going on, we may win in CSE. Otherwise combine will
5168 put the shifts back together again. */
5169 if (TARGET_MIPS16
5170 && optimize
5171 && GET_CODE (operands[2]) == CONST_INT
5172 && INTVAL (operands[2]) > 8
5173 && INTVAL (operands[2]) <= 16)
5174 {
5175 rtx temp = gen_reg_rtx (DImode);
5176
5177 emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
5178 emit_insn (gen_ashrdi3_internal (operands[0], temp,
5179 GEN_INT (INTVAL (operands[2]) - 8)));
5180 DONE;
5181 }
5182 })
5183
5184
5185 (define_insn "ashrdi3_internal"
5186 [(set (match_operand:DI 0 "register_operand" "=d")
5187 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5188 (match_operand:SI 2 "arith_operand" "dI")))]
5189 "TARGET_64BIT && !TARGET_MIPS16"
5190 {
5191 if (GET_CODE (operands[2]) == CONST_INT)
5192 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5193
5194 return "dsra\t%0,%1,%2";
5195 }
5196 [(set_attr "type" "shift")
5197 (set_attr "mode" "DI")])
5198
5199 (define_insn ""
5200 [(set (match_operand:DI 0 "register_operand" "=d,d")
5201 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5202 (match_operand:SI 2 "arith_operand" "d,I")))]
5203 "TARGET_64BIT && TARGET_MIPS16"
5204 {
5205 if (GET_CODE (operands[2]) == CONST_INT)
5206 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5207
5208 return "dsra\t%0,%2";
5209 }
5210 [(set_attr "type" "shift")
5211 (set_attr "mode" "DI")
5212 (set_attr_alternative "length"
5213 [(const_int 4)
5214 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5215 (const_int 4)
5216 (const_int 8))])])
5217
5218 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5219
5220 (define_split
5221 [(set (match_operand:DI 0 "register_operand")
5222 (ashiftrt:DI (match_operand:DI 1 "register_operand")
5223 (match_operand:SI 2 "const_int_operand")))]
5224 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5225 && reload_completed
5226 && GET_CODE (operands[2]) == CONST_INT
5227 && INTVAL (operands[2]) > 8
5228 && INTVAL (operands[2]) <= 16"
5229 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5230 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5231 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5232
5233 (define_expand "lshrsi3"
5234 [(set (match_operand:SI 0 "register_operand")
5235 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5236 (match_operand:SI 2 "arith_operand")))]
5237 ""
5238 {
5239 /* On the mips16, a shift of more than 8 is a four byte instruction,
5240 so, for a shift between 8 and 16, it is just as fast to do two
5241 shifts of 8 or less. If there is a lot of shifting going on, we
5242 may win in CSE. Otherwise combine will put the shifts back
5243 together again. */
5244 if (TARGET_MIPS16
5245 && optimize
5246 && GET_CODE (operands[2]) == CONST_INT
5247 && INTVAL (operands[2]) > 8
5248 && INTVAL (operands[2]) <= 16)
5249 {
5250 rtx temp = gen_reg_rtx (SImode);
5251
5252 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5253 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5254 GEN_INT (INTVAL (operands[2]) - 8)));
5255 DONE;
5256 }
5257 })
5258
5259 (define_insn "lshrsi3_internal1"
5260 [(set (match_operand:SI 0 "register_operand" "=d")
5261 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5262 (match_operand:SI 2 "arith_operand" "dI")))]
5263 "!TARGET_MIPS16"
5264 {
5265 if (GET_CODE (operands[2]) == CONST_INT)
5266 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5267
5268 return "srl\t%0,%1,%2";
5269 }
5270 [(set_attr "type" "shift")
5271 (set_attr "mode" "SI")])
5272
5273 (define_insn "lshrsi3_internal2"
5274 [(set (match_operand:SI 0 "register_operand" "=d,d")
5275 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5276 (match_operand:SI 2 "arith_operand" "d,I")))]
5277 "TARGET_MIPS16"
5278 {
5279 if (which_alternative == 0)
5280 return "srl\t%0,%2";
5281
5282 if (GET_CODE (operands[2]) == CONST_INT)
5283 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5284
5285 return "srl\t%0,%1,%2";
5286 }
5287 [(set_attr "type" "shift")
5288 (set_attr "mode" "SI")
5289 (set_attr_alternative "length"
5290 [(const_int 4)
5291 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5292 (const_int 4)
5293 (const_int 8))])])
5294
5295
5296 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5297
5298 (define_split
5299 [(set (match_operand:SI 0 "register_operand")
5300 (lshiftrt:SI (match_operand:SI 1 "register_operand")
5301 (match_operand:SI 2 "const_int_operand")))]
5302 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5303 && GET_CODE (operands[2]) == CONST_INT
5304 && INTVAL (operands[2]) > 8
5305 && INTVAL (operands[2]) <= 16"
5306 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5307 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5308 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5309
5310 ;; If we load a byte on the mips16 as a bitfield, the resulting
5311 ;; sequence of instructions is too complicated for combine, because it
5312 ;; involves four instructions: a load, a shift, a constant load into a
5313 ;; register, and an and (the key problem here is that the mips16 does
5314 ;; not have and immediate). We recognize a shift of a load in order
5315 ;; to make it simple enough for combine to understand.
5316 ;;
5317 ;; The length here is the worst case: the length of the split version
5318 ;; will be more accurate.
5319 (define_insn_and_split ""
5320 [(set (match_operand:SI 0 "register_operand" "=d")
5321 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5322 (match_operand:SI 2 "immediate_operand" "I")))]
5323 "TARGET_MIPS16"
5324 "#"
5325 ""
5326 [(set (match_dup 0) (match_dup 1))
5327 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5328 ""
5329 [(set_attr "type" "load")
5330 (set_attr "mode" "SI")
5331 (set_attr "length" "16")])
5332
5333 (define_expand "lshrdi3"
5334 [(set (match_operand:DI 0 "register_operand")
5335 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5336 (match_operand:SI 2 "arith_operand")))]
5337 "TARGET_64BIT"
5338 {
5339 /* On the mips16, a shift of more than 8 is a four byte
5340 instruction, so, for a shift between 8 and 16, it is just as
5341 fast to do two shifts of 8 or less. If there is a lot of
5342 shifting going on, we may win in CSE. Otherwise combine will
5343 put the shifts back together again. */
5344 if (TARGET_MIPS16
5345 && optimize
5346 && GET_CODE (operands[2]) == CONST_INT
5347 && INTVAL (operands[2]) > 8
5348 && INTVAL (operands[2]) <= 16)
5349 {
5350 rtx temp = gen_reg_rtx (DImode);
5351
5352 emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
5353 emit_insn (gen_lshrdi3_internal (operands[0], temp,
5354 GEN_INT (INTVAL (operands[2]) - 8)));
5355 DONE;
5356 }
5357 })
5358
5359
5360 (define_insn "lshrdi3_internal"
5361 [(set (match_operand:DI 0 "register_operand" "=d")
5362 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5363 (match_operand:SI 2 "arith_operand" "dI")))]
5364 "TARGET_64BIT && !TARGET_MIPS16"
5365 {
5366 if (GET_CODE (operands[2]) == CONST_INT)
5367 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5368
5369 return "dsrl\t%0,%1,%2";
5370 }
5371 [(set_attr "type" "shift")
5372 (set_attr "mode" "DI")])
5373
5374 (define_insn ""
5375 [(set (match_operand:DI 0 "register_operand" "=d,d")
5376 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5377 (match_operand:SI 2 "arith_operand" "d,I")))]
5378 "TARGET_64BIT && TARGET_MIPS16"
5379 {
5380 if (GET_CODE (operands[2]) == CONST_INT)
5381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5382
5383 return "dsrl\t%0,%2";
5384 }
5385 [(set_attr "type" "shift")
5386 (set_attr "mode" "DI")
5387 (set_attr_alternative "length"
5388 [(const_int 4)
5389 (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
5390 (const_int 4)
5391 (const_int 8))])])
5392
5393 (define_insn "rotrsi3"
5394 [(set (match_operand:SI 0 "register_operand" "=d")
5395 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
5396 (match_operand:SI 2 "arith_operand" "dn")))]
5397 "ISA_HAS_ROTR_SI"
5398 {
5399 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
5400 return "rorv\t%0,%1,%2";
5401
5402 if ((GET_CODE (operands[2]) == CONST_INT)
5403 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
5404 abort ();
5405
5406 return "ror\t%0,%1,%2";
5407 }
5408 [(set_attr "type" "shift")
5409 (set_attr "mode" "SI")])
5410
5411 (define_insn "rotrdi3"
5412 [(set (match_operand:DI 0 "register_operand" "=d")
5413 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
5414 (match_operand:DI 2 "arith_operand" "dn")))]
5415 "ISA_HAS_ROTR_DI"
5416 {
5417 if (TARGET_SR71K)
5418 {
5419 if (GET_CODE (operands[2]) != CONST_INT)
5420 return "drorv\t%0,%1,%2";
5421
5422 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
5423 return "dror32\t%0,%1,%2";
5424 }
5425
5426 if ((GET_CODE (operands[2]) == CONST_INT)
5427 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
5428 abort ();
5429
5430 return "dror\t%0,%1,%2";
5431 }
5432 [(set_attr "type" "shift")
5433 (set_attr "mode" "DI")])
5434
5435
5436 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5437
5438 (define_split
5439 [(set (match_operand:DI 0 "register_operand")
5440 (lshiftrt:DI (match_operand:DI 1 "register_operand")
5441 (match_operand:SI 2 "const_int_operand")))]
5442 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5443 && GET_CODE (operands[2]) == CONST_INT
5444 && INTVAL (operands[2]) > 8
5445 && INTVAL (operands[2]) <= 16"
5446 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
5447 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
5448 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5449 \f
5450 ;;
5451 ;; ....................
5452 ;;
5453 ;; COMPARISONS
5454 ;;
5455 ;; ....................
5456
5457 ;; Flow here is rather complex:
5458 ;;
5459 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
5460 ;; into cmp_operands[] but generates no RTL.
5461 ;;
5462 ;; 2) The appropriate branch define_expand is called, which then
5463 ;; creates the appropriate RTL for the comparison and branch.
5464 ;; Different CC modes are used, based on what type of branch is
5465 ;; done, so that we can constrain things appropriately. There
5466 ;; are assumptions in the rest of GCC that break if we fold the
5467 ;; operands into the branches for integer operations, and use cc0
5468 ;; for floating point, so we use the fp status register instead.
5469 ;; If needed, an appropriate temporary is created to hold the
5470 ;; of the integer compare.
5471
5472 (define_expand "cmpsi"
5473 [(set (cc0)
5474 (compare:CC (match_operand:SI 0 "register_operand")
5475 (match_operand:SI 1 "arith_operand")))]
5476 ""
5477 {
5478 cmp_operands[0] = operands[0];
5479 cmp_operands[1] = operands[1];
5480 DONE;
5481 })
5482
5483 (define_expand "cmpdi"
5484 [(set (cc0)
5485 (compare:CC (match_operand:DI 0 "register_operand")
5486 (match_operand:DI 1 "arith_operand")))]
5487 "TARGET_64BIT"
5488 {
5489 cmp_operands[0] = operands[0];
5490 cmp_operands[1] = operands[1];
5491 DONE;
5492 })
5493
5494 (define_expand "cmpdf"
5495 [(set (cc0)
5496 (compare:CC (match_operand:DF 0 "register_operand")
5497 (match_operand:DF 1 "register_operand")))]
5498 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5499 {
5500 cmp_operands[0] = operands[0];
5501 cmp_operands[1] = operands[1];
5502 DONE;
5503 })
5504
5505 (define_expand "cmpsf"
5506 [(set (cc0)
5507 (compare:CC (match_operand:SF 0 "register_operand")
5508 (match_operand:SF 1 "register_operand")))]
5509 "TARGET_HARD_FLOAT"
5510 {
5511 cmp_operands[0] = operands[0];
5512 cmp_operands[1] = operands[1];
5513 DONE;
5514 })
5515 \f
5516 ;;
5517 ;; ....................
5518 ;;
5519 ;; CONDITIONAL BRANCHES
5520 ;;
5521 ;; ....................
5522
5523 ;; Conditional branches on floating-point equality tests.
5524
5525 (define_insn "branch_fp"
5526 [(set (pc)
5527 (if_then_else
5528 (match_operator:CC 0 "cmp_op"
5529 [(match_operand:CC 2 "register_operand" "z")
5530 (const_int 0)])
5531 (label_ref (match_operand 1 "" ""))
5532 (pc)))]
5533 "TARGET_HARD_FLOAT"
5534 {
5535 return mips_output_conditional_branch (insn,
5536 operands,
5537 /*two_operands_p=*/0,
5538 /*float_p=*/1,
5539 /*inverted_p=*/0,
5540 get_attr_length (insn));
5541 }
5542 [(set_attr "type" "branch")
5543 (set_attr "mode" "none")])
5544
5545 (define_insn "branch_fp_inverted"
5546 [(set (pc)
5547 (if_then_else
5548 (match_operator:CC 0 "cmp_op"
5549 [(match_operand:CC 2 "register_operand" "z")
5550 (const_int 0)])
5551 (pc)
5552 (label_ref (match_operand 1 "" ""))))]
5553 "TARGET_HARD_FLOAT"
5554 {
5555 return mips_output_conditional_branch (insn,
5556 operands,
5557 /*two_operands_p=*/0,
5558 /*float_p=*/1,
5559 /*inverted_p=*/1,
5560 get_attr_length (insn));
5561 }
5562 [(set_attr "type" "branch")
5563 (set_attr "mode" "none")])
5564
5565 ;; Conditional branches on comparisons with zero.
5566
5567 (define_insn "branch_zero"
5568 [(set (pc)
5569 (if_then_else
5570 (match_operator:SI 0 "cmp_op"
5571 [(match_operand:SI 2 "register_operand" "d")
5572 (const_int 0)])
5573 (label_ref (match_operand 1 "" ""))
5574 (pc)))]
5575 "!TARGET_MIPS16"
5576 {
5577 return mips_output_conditional_branch (insn,
5578 operands,
5579 /*two_operands_p=*/0,
5580 /*float_p=*/0,
5581 /*inverted_p=*/0,
5582 get_attr_length (insn));
5583 }
5584 [(set_attr "type" "branch")
5585 (set_attr "mode" "none")])
5586
5587 (define_insn "branch_zero_inverted"
5588 [(set (pc)
5589 (if_then_else
5590 (match_operator:SI 0 "cmp_op"
5591 [(match_operand:SI 2 "register_operand" "d")
5592 (const_int 0)])
5593 (pc)
5594 (label_ref (match_operand 1 "" ""))))]
5595 "!TARGET_MIPS16"
5596 {
5597 return mips_output_conditional_branch (insn,
5598 operands,
5599 /*two_operands_p=*/0,
5600 /*float_p=*/0,
5601 /*inverted_p=*/1,
5602 get_attr_length (insn));
5603 }
5604 [(set_attr "type" "branch")
5605 (set_attr "mode" "none")])
5606
5607 (define_insn "branch_zero_di"
5608 [(set (pc)
5609 (if_then_else
5610 (match_operator:DI 0 "cmp_op"
5611 [(match_operand:DI 2 "register_operand" "d")
5612 (const_int 0)])
5613 (label_ref (match_operand 1 "" ""))
5614 (pc)))]
5615 "!TARGET_MIPS16"
5616 {
5617 return mips_output_conditional_branch (insn,
5618 operands,
5619 /*two_operands_p=*/0,
5620 /*float_p=*/0,
5621 /*inverted_p=*/0,
5622 get_attr_length (insn));
5623 }
5624 [(set_attr "type" "branch")
5625 (set_attr "mode" "none")])
5626
5627 (define_insn "branch_zero_di_inverted"
5628 [(set (pc)
5629 (if_then_else
5630 (match_operator:DI 0 "cmp_op"
5631 [(match_operand:DI 2 "register_operand" "d")
5632 (const_int 0)])
5633 (pc)
5634 (label_ref (match_operand 1 "" ""))))]
5635 "!TARGET_MIPS16"
5636 {
5637 return mips_output_conditional_branch (insn,
5638 operands,
5639 /*two_operands_p=*/0,
5640 /*float_p=*/0,
5641 /*inverted_p=*/1,
5642 get_attr_length (insn));
5643 }
5644 [(set_attr "type" "branch")
5645 (set_attr "mode" "none")])
5646
5647 ;; Conditional branch on equality comparison.
5648
5649 (define_insn "branch_equality"
5650 [(set (pc)
5651 (if_then_else
5652 (match_operator:SI 0 "equality_op"
5653 [(match_operand:SI 2 "register_operand" "d")
5654 (match_operand:SI 3 "register_operand" "d")])
5655 (label_ref (match_operand 1 "" ""))
5656 (pc)))]
5657 "!TARGET_MIPS16"
5658 {
5659 return mips_output_conditional_branch (insn,
5660 operands,
5661 /*two_operands_p=*/1,
5662 /*float_p=*/0,
5663 /*inverted_p=*/0,
5664 get_attr_length (insn));
5665 }
5666 [(set_attr "type" "branch")
5667 (set_attr "mode" "none")])
5668
5669 (define_insn "branch_equality_di"
5670 [(set (pc)
5671 (if_then_else
5672 (match_operator:DI 0 "equality_op"
5673 [(match_operand:DI 2 "register_operand" "d")
5674 (match_operand:DI 3 "register_operand" "d")])
5675 (label_ref (match_operand 1 "" ""))
5676 (pc)))]
5677 "!TARGET_MIPS16"
5678 {
5679 return mips_output_conditional_branch (insn,
5680 operands,
5681 /*two_operands_p=*/1,
5682 /*float_p=*/0,
5683 /*inverted_p=*/0,
5684 get_attr_length (insn));
5685 }
5686 [(set_attr "type" "branch")
5687 (set_attr "mode" "none")])
5688
5689 (define_insn "branch_equality_inverted"
5690 [(set (pc)
5691 (if_then_else
5692 (match_operator:SI 0 "equality_op"
5693 [(match_operand:SI 2 "register_operand" "d")
5694 (match_operand:SI 3 "register_operand" "d")])
5695 (pc)
5696 (label_ref (match_operand 1 "" ""))))]
5697 "!TARGET_MIPS16"
5698 {
5699 return mips_output_conditional_branch (insn,
5700 operands,
5701 /*two_operands_p=*/1,
5702 /*float_p=*/0,
5703 /*inverted_p=*/1,
5704 get_attr_length (insn));
5705 }
5706 [(set_attr "type" "branch")
5707 (set_attr "mode" "none")])
5708
5709 (define_insn "branch_equality_di_inverted"
5710 [(set (pc)
5711 (if_then_else
5712 (match_operator:DI 0 "equality_op"
5713 [(match_operand:DI 2 "register_operand" "d")
5714 (match_operand:DI 3 "register_operand" "d")])
5715 (pc)
5716 (label_ref (match_operand 1 "" ""))))]
5717 "!TARGET_MIPS16"
5718 {
5719 return mips_output_conditional_branch (insn,
5720 operands,
5721 /*two_operands_p=*/1,
5722 /*float_p=*/0,
5723 /*inverted_p=*/1,
5724 get_attr_length (insn));
5725 }
5726 [(set_attr "type" "branch")
5727 (set_attr "mode" "none")])
5728
5729 ;; MIPS16 branches
5730
5731 (define_insn ""
5732 [(set (pc)
5733 (if_then_else (match_operator:SI 0 "equality_op"
5734 [(match_operand:SI 1 "register_operand" "d,t")
5735 (const_int 0)])
5736 (match_operand 2 "pc_or_label_operand" "")
5737 (match_operand 3 "pc_or_label_operand" "")))]
5738 "TARGET_MIPS16"
5739 {
5740 if (operands[2] != pc_rtx)
5741 {
5742 if (which_alternative == 0)
5743 return "b%C0z\t%1,%2";
5744 else
5745 return "bt%C0z\t%2";
5746 }
5747 else
5748 {
5749 if (which_alternative == 0)
5750 return "b%N0z\t%1,%3";
5751 else
5752 return "bt%N0z\t%3";
5753 }
5754 }
5755 [(set_attr "type" "branch")
5756 (set_attr "mode" "none")
5757 (set_attr "length" "8")])
5758
5759 (define_insn ""
5760 [(set (pc)
5761 (if_then_else (match_operator:DI 0 "equality_op"
5762 [(match_operand:DI 1 "register_operand" "d,t")
5763 (const_int 0)])
5764 (match_operand 2 "pc_or_label_operand" "")
5765 (match_operand 3 "pc_or_label_operand" "")))]
5766 "TARGET_MIPS16"
5767 {
5768 if (operands[2] != pc_rtx)
5769 {
5770 if (which_alternative == 0)
5771 return "b%C0z\t%1,%2";
5772 else
5773 return "bt%C0z\t%2";
5774 }
5775 else
5776 {
5777 if (which_alternative == 0)
5778 return "b%N0z\t%1,%3";
5779 else
5780 return "bt%N0z\t%3";
5781 }
5782 }
5783 [(set_attr "type" "branch")
5784 (set_attr "mode" "none")
5785 (set_attr "length" "8")])
5786
5787 (define_expand "bunordered"
5788 [(set (pc)
5789 (if_then_else (unordered:CC (cc0)
5790 (const_int 0))
5791 (label_ref (match_operand 0 ""))
5792 (pc)))]
5793 ""
5794 {
5795 gen_conditional_branch (operands, UNORDERED);
5796 DONE;
5797 })
5798
5799 (define_expand "bordered"
5800 [(set (pc)
5801 (if_then_else (ordered:CC (cc0)
5802 (const_int 0))
5803 (label_ref (match_operand 0 ""))
5804 (pc)))]
5805 ""
5806 {
5807 gen_conditional_branch (operands, ORDERED);
5808 DONE;
5809 })
5810
5811 (define_expand "bunlt"
5812 [(set (pc)
5813 (if_then_else (unlt:CC (cc0)
5814 (const_int 0))
5815 (label_ref (match_operand 0 ""))
5816 (pc)))]
5817 ""
5818 {
5819 gen_conditional_branch (operands, UNLT);
5820 DONE;
5821 })
5822
5823 (define_expand "bunge"
5824 [(set (pc)
5825 (if_then_else (unge:CC (cc0)
5826 (const_int 0))
5827 (label_ref (match_operand 0 ""))
5828 (pc)))]
5829 ""
5830 {
5831 gen_conditional_branch (operands, UNGE);
5832 DONE;
5833 })
5834
5835 (define_expand "buneq"
5836 [(set (pc)
5837 (if_then_else (uneq:CC (cc0)
5838 (const_int 0))
5839 (label_ref (match_operand 0 ""))
5840 (pc)))]
5841 ""
5842 {
5843 gen_conditional_branch (operands, UNEQ);
5844 DONE;
5845 })
5846
5847 (define_expand "bltgt"
5848 [(set (pc)
5849 (if_then_else (ltgt:CC (cc0)
5850 (const_int 0))
5851 (label_ref (match_operand 0 ""))
5852 (pc)))]
5853 ""
5854 {
5855 gen_conditional_branch (operands, LTGT);
5856 DONE;
5857 })
5858
5859 (define_expand "bunle"
5860 [(set (pc)
5861 (if_then_else (unle:CC (cc0)
5862 (const_int 0))
5863 (label_ref (match_operand 0 ""))
5864 (pc)))]
5865 ""
5866 {
5867 gen_conditional_branch (operands, UNLE);
5868 DONE;
5869 })
5870
5871 (define_expand "bungt"
5872 [(set (pc)
5873 (if_then_else (ungt:CC (cc0)
5874 (const_int 0))
5875 (label_ref (match_operand 0 ""))
5876 (pc)))]
5877 ""
5878 {
5879 gen_conditional_branch (operands, UNGT);
5880 DONE;
5881 })
5882
5883 (define_expand "beq"
5884 [(set (pc)
5885 (if_then_else (eq:CC (cc0)
5886 (const_int 0))
5887 (label_ref (match_operand 0 ""))
5888 (pc)))]
5889 ""
5890 {
5891 gen_conditional_branch (operands, EQ);
5892 DONE;
5893 })
5894
5895 (define_expand "bne"
5896 [(set (pc)
5897 (if_then_else (ne:CC (cc0)
5898 (const_int 0))
5899 (label_ref (match_operand 0 ""))
5900 (pc)))]
5901 ""
5902 {
5903 gen_conditional_branch (operands, NE);
5904 DONE;
5905 })
5906
5907 (define_expand "bgt"
5908 [(set (pc)
5909 (if_then_else (gt:CC (cc0)
5910 (const_int 0))
5911 (label_ref (match_operand 0 ""))
5912 (pc)))]
5913 ""
5914 {
5915 gen_conditional_branch (operands, GT);
5916 DONE;
5917 })
5918
5919 (define_expand "bge"
5920 [(set (pc)
5921 (if_then_else (ge:CC (cc0)
5922 (const_int 0))
5923 (label_ref (match_operand 0 ""))
5924 (pc)))]
5925 ""
5926 {
5927 gen_conditional_branch (operands, GE);
5928 DONE;
5929 })
5930
5931 (define_expand "blt"
5932 [(set (pc)
5933 (if_then_else (lt:CC (cc0)
5934 (const_int 0))
5935 (label_ref (match_operand 0 ""))
5936 (pc)))]
5937 ""
5938 {
5939 gen_conditional_branch (operands, LT);
5940 DONE;
5941 })
5942
5943 (define_expand "ble"
5944 [(set (pc)
5945 (if_then_else (le:CC (cc0)
5946 (const_int 0))
5947 (label_ref (match_operand 0 ""))
5948 (pc)))]
5949 ""
5950 {
5951 gen_conditional_branch (operands, LE);
5952 DONE;
5953 })
5954
5955 (define_expand "bgtu"
5956 [(set (pc)
5957 (if_then_else (gtu:CC (cc0)
5958 (const_int 0))
5959 (label_ref (match_operand 0 ""))
5960 (pc)))]
5961 ""
5962 {
5963 gen_conditional_branch (operands, GTU);
5964 DONE;
5965 })
5966
5967 (define_expand "bgeu"
5968 [(set (pc)
5969 (if_then_else (geu:CC (cc0)
5970 (const_int 0))
5971 (label_ref (match_operand 0 ""))
5972 (pc)))]
5973 ""
5974 {
5975 gen_conditional_branch (operands, GEU);
5976 DONE;
5977 })
5978
5979 (define_expand "bltu"
5980 [(set (pc)
5981 (if_then_else (ltu:CC (cc0)
5982 (const_int 0))
5983 (label_ref (match_operand 0 ""))
5984 (pc)))]
5985 ""
5986 {
5987 gen_conditional_branch (operands, LTU);
5988 DONE;
5989 })
5990
5991 (define_expand "bleu"
5992 [(set (pc)
5993 (if_then_else (leu:CC (cc0)
5994 (const_int 0))
5995 (label_ref (match_operand 0 ""))
5996 (pc)))]
5997 ""
5998 {
5999 gen_conditional_branch (operands, LEU);
6000 DONE;
6001 })
6002 \f
6003 ;;
6004 ;; ....................
6005 ;;
6006 ;; SETTING A REGISTER FROM A COMPARISON
6007 ;;
6008 ;; ....................
6009
6010 (define_expand "seq"
6011 [(set (match_operand:SI 0 "register_operand")
6012 (eq:SI (match_dup 1)
6013 (match_dup 2)))]
6014 ""
6015 {
6016 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6017 FAIL;
6018
6019 gen_int_relational (EQ, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6020 DONE;
6021 })
6022
6023
6024 (define_insn "*seq_si"
6025 [(set (match_operand:SI 0 "register_operand" "=d")
6026 (eq:SI (match_operand:SI 1 "register_operand" "d")
6027 (const_int 0)))]
6028 "!TARGET_MIPS16"
6029 "sltu\t%0,%1,1"
6030 [(set_attr "type" "slt")
6031 (set_attr "mode" "SI")])
6032
6033 (define_insn "*seq_si_mips16"
6034 [(set (match_operand:SI 0 "register_operand" "=t")
6035 (eq:SI (match_operand:SI 1 "register_operand" "d")
6036 (const_int 0)))]
6037 "TARGET_MIPS16"
6038 "sltu\t%1,1"
6039 [(set_attr "type" "slt")
6040 (set_attr "mode" "SI")])
6041
6042 (define_insn "*seq_di"
6043 [(set (match_operand:DI 0 "register_operand" "=d")
6044 (eq:DI (match_operand:DI 1 "register_operand" "d")
6045 (const_int 0)))]
6046 "TARGET_64BIT && !TARGET_MIPS16"
6047 "sltu\t%0,%1,1"
6048 [(set_attr "type" "slt")
6049 (set_attr "mode" "DI")])
6050
6051 (define_insn "*seq_di_mips16"
6052 [(set (match_operand:DI 0 "register_operand" "=t")
6053 (eq:DI (match_operand:DI 1 "register_operand" "d")
6054 (const_int 0)))]
6055 "TARGET_64BIT && TARGET_MIPS16"
6056 "sltu\t%1,1"
6057 [(set_attr "type" "slt")
6058 (set_attr "mode" "DI")])
6059
6060 ;; On the mips16 the default code is better than using sltu.
6061
6062 (define_expand "sne"
6063 [(set (match_operand:SI 0 "register_operand")
6064 (ne:SI (match_dup 1)
6065 (match_dup 2)))]
6066 "!TARGET_MIPS16"
6067 {
6068 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6069 FAIL;
6070
6071 gen_int_relational (NE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6072 DONE;
6073 })
6074
6075 (define_insn "*sne_si"
6076 [(set (match_operand:SI 0 "register_operand" "=d")
6077 (ne:SI (match_operand:SI 1 "register_operand" "d")
6078 (const_int 0)))]
6079 "!TARGET_MIPS16"
6080 "sltu\t%0,%.,%1"
6081 [(set_attr "type" "slt")
6082 (set_attr "mode" "SI")])
6083
6084 (define_insn "*sne_di"
6085 [(set (match_operand:DI 0 "register_operand" "=d")
6086 (ne:DI (match_operand:DI 1 "register_operand" "d")
6087 (const_int 0)))]
6088 "TARGET_64BIT && !TARGET_MIPS16"
6089 "sltu\t%0,%.,%1"
6090 [(set_attr "type" "slt")
6091 (set_attr "mode" "DI")])
6092
6093 (define_expand "sgt"
6094 [(set (match_operand:SI 0 "register_operand")
6095 (gt:SI (match_dup 1)
6096 (match_dup 2)))]
6097 ""
6098 {
6099 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6100 FAIL;
6101
6102 gen_int_relational (GT, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6103 DONE;
6104 })
6105
6106 (define_insn "*sgt_si"
6107 [(set (match_operand:SI 0 "register_operand" "=d")
6108 (gt:SI (match_operand:SI 1 "register_operand" "d")
6109 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6110 "!TARGET_MIPS16"
6111 "slt\t%0,%z2,%1"
6112 [(set_attr "type" "slt")
6113 (set_attr "mode" "SI")])
6114
6115 (define_insn "*sgt_si_mips16"
6116 [(set (match_operand:SI 0 "register_operand" "=t")
6117 (gt:SI (match_operand:SI 1 "register_operand" "d")
6118 (match_operand:SI 2 "register_operand" "d")))]
6119 "TARGET_MIPS16"
6120 "slt\t%2,%1"
6121 [(set_attr "type" "slt")
6122 (set_attr "mode" "SI")])
6123
6124 (define_insn "*sgt_di"
6125 [(set (match_operand:DI 0 "register_operand" "=d")
6126 (gt:DI (match_operand:DI 1 "register_operand" "d")
6127 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6128 "TARGET_64BIT && !TARGET_MIPS16"
6129 "slt\t%0,%z2,%1"
6130 [(set_attr "type" "slt")
6131 (set_attr "mode" "DI")])
6132
6133 (define_insn "*sgt_di_mips16"
6134 [(set (match_operand:DI 0 "register_operand" "=t")
6135 (gt:DI (match_operand:DI 1 "register_operand" "d")
6136 (match_operand:DI 2 "register_operand" "d")))]
6137 "TARGET_64BIT && TARGET_MIPS16"
6138 "slt\t%2,%1"
6139 [(set_attr "type" "slt")
6140 (set_attr "mode" "DI")])
6141
6142 (define_expand "sge"
6143 [(set (match_operand:SI 0 "register_operand")
6144 (ge:SI (match_dup 1)
6145 (match_dup 2)))]
6146 ""
6147 {
6148 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6149 FAIL;
6150
6151 gen_int_relational (GE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6152 DONE;
6153 })
6154
6155 (define_expand "slt"
6156 [(set (match_operand:SI 0 "register_operand")
6157 (lt:SI (match_dup 1)
6158 (match_dup 2)))]
6159 ""
6160 {
6161 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6162 FAIL;
6163
6164 gen_int_relational (LT, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6165 DONE;
6166 })
6167
6168 (define_insn "*slt_si"
6169 [(set (match_operand:SI 0 "register_operand" "=d")
6170 (lt:SI (match_operand:SI 1 "register_operand" "d")
6171 (match_operand:SI 2 "arith_operand" "dI")))]
6172 "!TARGET_MIPS16"
6173 "slt\t%0,%1,%2"
6174 [(set_attr "type" "slt")
6175 (set_attr "mode" "SI")])
6176
6177 (define_insn "*slt_si_mips16"
6178 [(set (match_operand:SI 0 "register_operand" "=t,t")
6179 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
6180 (match_operand:SI 2 "arith_operand" "d,I")))]
6181 "TARGET_MIPS16"
6182 "slt\t%1,%2"
6183 [(set_attr "type" "slt")
6184 (set_attr "mode" "SI")
6185 (set_attr_alternative "length"
6186 [(const_int 4)
6187 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6188 (const_int 4)
6189 (const_int 8))])])
6190
6191 (define_insn "*slt_di"
6192 [(set (match_operand:DI 0 "register_operand" "=d")
6193 (lt:DI (match_operand:DI 1 "register_operand" "d")
6194 (match_operand:DI 2 "arith_operand" "dI")))]
6195 "TARGET_64BIT && !TARGET_MIPS16"
6196 "slt\t%0,%1,%2"
6197 [(set_attr "type" "slt")
6198 (set_attr "mode" "DI")])
6199
6200 (define_insn "*slt_di_mips16"
6201 [(set (match_operand:DI 0 "register_operand" "=t,t")
6202 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
6203 (match_operand:DI 2 "arith_operand" "d,I")))]
6204 "TARGET_64BIT && TARGET_MIPS16"
6205 "slt\t%1,%2"
6206 [(set_attr "type" "slt")
6207 (set_attr "mode" "DI")
6208 (set_attr_alternative "length"
6209 [(const_int 4)
6210 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6211 (const_int 4)
6212 (const_int 8))])])
6213
6214 (define_expand "sle"
6215 [(set (match_operand:SI 0 "register_operand")
6216 (le:SI (match_dup 1)
6217 (match_dup 2)))]
6218 ""
6219 {
6220 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6221 FAIL;
6222
6223 gen_int_relational (LE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6224 DONE;
6225 })
6226
6227 (define_insn "*sle_si"
6228 [(set (match_operand:SI 0 "register_operand" "=d")
6229 (le:SI (match_operand:SI 1 "register_operand" "d")
6230 (match_operand:SI 2 "small_int" "I")))]
6231 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6232 {
6233 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6234 return "slt\t%0,%1,%2";
6235 }
6236 [(set_attr "type" "slt")
6237 (set_attr "mode" "SI")])
6238
6239 (define_insn "*sle_si_mips16"
6240 [(set (match_operand:SI 0 "register_operand" "=t")
6241 (le:SI (match_operand:SI 1 "register_operand" "d")
6242 (match_operand:SI 2 "small_int" "I")))]
6243 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6244 {
6245 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6246 return "slt\t%1,%2";
6247 }
6248 [(set_attr "type" "slt")
6249 (set_attr "mode" "SI")
6250 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6251 (const_int 4)
6252 (const_int 8)))])
6253
6254 (define_insn "*sle_di"
6255 [(set (match_operand:DI 0 "register_operand" "=d")
6256 (le:DI (match_operand:DI 1 "register_operand" "d")
6257 (match_operand:DI 2 "small_int" "I")))]
6258 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6259 {
6260 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6261 return "slt\t%0,%1,%2";
6262 }
6263 [(set_attr "type" "slt")
6264 (set_attr "mode" "DI")])
6265
6266 (define_insn "*sle_di_mips16"
6267 [(set (match_operand:DI 0 "register_operand" "=t")
6268 (le:DI (match_operand:DI 1 "register_operand" "d")
6269 (match_operand:DI 2 "small_int" "I")))]
6270 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6271 {
6272 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6273 return "slt\t%1,%2";
6274 }
6275 [(set_attr "type" "slt")
6276 (set_attr "mode" "DI")
6277 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6278 (const_int 4)
6279 (const_int 8)))])
6280
6281 (define_expand "sgtu"
6282 [(set (match_operand:SI 0 "register_operand")
6283 (gtu:SI (match_dup 1)
6284 (match_dup 2)))]
6285 ""
6286 {
6287 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6288 FAIL;
6289
6290 gen_int_relational (GTU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6291 DONE;
6292 })
6293
6294 (define_insn "*sgtu_si"
6295 [(set (match_operand:SI 0 "register_operand" "=d")
6296 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6297 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
6298 "!TARGET_MIPS16"
6299 "sltu\t%0,%z2,%1"
6300 [(set_attr "type" "slt")
6301 (set_attr "mode" "SI")])
6302
6303 (define_insn "*sgtu_si_mips16"
6304 [(set (match_operand:SI 0 "register_operand" "=t")
6305 (gtu:SI (match_operand:SI 1 "register_operand" "d")
6306 (match_operand:SI 2 "register_operand" "d")))]
6307 "TARGET_MIPS16"
6308 "sltu\t%2,%1"
6309 [(set_attr "type" "slt")
6310 (set_attr "mode" "SI")])
6311
6312 (define_insn "*sgtu_di"
6313 [(set (match_operand:DI 0 "register_operand" "=d")
6314 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6315 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
6316 "TARGET_64BIT && !TARGET_MIPS16"
6317 "sltu\t%0,%z2,%1"
6318 [(set_attr "type" "slt")
6319 (set_attr "mode" "DI")])
6320
6321 (define_insn "*sgtu_di_mips16"
6322 [(set (match_operand:DI 0 "register_operand" "=t")
6323 (gtu:DI (match_operand:DI 1 "register_operand" "d")
6324 (match_operand:DI 2 "register_operand" "d")))]
6325 "TARGET_64BIT && TARGET_MIPS16"
6326 "sltu\t%2,%1"
6327 [(set_attr "type" "slt")
6328 (set_attr "mode" "DI")])
6329
6330 (define_expand "sgeu"
6331 [(set (match_operand:SI 0 "register_operand")
6332 (geu:SI (match_dup 1)
6333 (match_dup 2)))]
6334 ""
6335 {
6336 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6337 FAIL;
6338
6339 gen_int_relational (GEU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6340 DONE;
6341 })
6342
6343 (define_expand "sltu"
6344 [(set (match_operand:SI 0 "register_operand")
6345 (ltu:SI (match_dup 1)
6346 (match_dup 2)))]
6347 ""
6348 {
6349 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6350 FAIL;
6351
6352 gen_int_relational (LTU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6353 DONE;
6354 })
6355
6356 (define_insn "*sltu_si"
6357 [(set (match_operand:SI 0 "register_operand" "=d")
6358 (ltu:SI (match_operand:SI 1 "register_operand" "d")
6359 (match_operand:SI 2 "arith_operand" "dI")))]
6360 "!TARGET_MIPS16"
6361 "sltu\t%0,%1,%2"
6362 [(set_attr "type" "slt")
6363 (set_attr "mode" "SI")])
6364
6365 (define_insn "*sltu_si_mips16"
6366 [(set (match_operand:SI 0 "register_operand" "=t,t")
6367 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
6368 (match_operand:SI 2 "arith_operand" "d,I")))]
6369 "TARGET_MIPS16"
6370 "sltu\t%1,%2"
6371 [(set_attr "type" "slt")
6372 (set_attr "mode" "SI")
6373 (set_attr_alternative "length"
6374 [(const_int 4)
6375 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6376 (const_int 4)
6377 (const_int 8))])])
6378
6379 (define_insn "*sltu_di"
6380 [(set (match_operand:DI 0 "register_operand" "=d")
6381 (ltu:DI (match_operand:DI 1 "register_operand" "d")
6382 (match_operand:DI 2 "arith_operand" "dI")))]
6383 "TARGET_64BIT && !TARGET_MIPS16"
6384 "sltu\t%0,%1,%2"
6385 [(set_attr "type" "slt")
6386 (set_attr "mode" "DI")])
6387
6388 (define_insn "*sltu_di_mips16"
6389 [(set (match_operand:DI 0 "register_operand" "=t,t")
6390 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
6391 (match_operand:DI 2 "arith_operand" "d,I")))]
6392 "TARGET_64BIT && TARGET_MIPS16"
6393 "sltu\t%1,%2"
6394 [(set_attr "type" "slt")
6395 (set_attr "mode" "DI")
6396 (set_attr_alternative "length"
6397 [(const_int 4)
6398 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
6399 (const_int 4)
6400 (const_int 8))])])
6401
6402 (define_expand "sleu"
6403 [(set (match_operand:SI 0 "register_operand")
6404 (leu:SI (match_dup 1)
6405 (match_dup 2)))]
6406 ""
6407 {
6408 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
6409 FAIL;
6410
6411 gen_int_relational (LEU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
6412 DONE;
6413 })
6414
6415 (define_insn "*sleu_si"
6416 [(set (match_operand:SI 0 "register_operand" "=d")
6417 (leu:SI (match_operand:SI 1 "register_operand" "d")
6418 (match_operand:SI 2 "small_int" "I")))]
6419 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6420 {
6421 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6422 return "sltu\t%0,%1,%2";
6423 }
6424 [(set_attr "type" "slt")
6425 (set_attr "mode" "SI")])
6426
6427 (define_insn "*sleu_si_mips16"
6428 [(set (match_operand:SI 0 "register_operand" "=t")
6429 (leu:SI (match_operand:SI 1 "register_operand" "d")
6430 (match_operand:SI 2 "small_int" "I")))]
6431 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6432 {
6433 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6434 return "sltu\t%1,%2";
6435 }
6436 [(set_attr "type" "slt")
6437 (set_attr "mode" "SI")
6438 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6439 (const_int 4)
6440 (const_int 8)))])
6441
6442 (define_insn "*sleu_di"
6443 [(set (match_operand:DI 0 "register_operand" "=d")
6444 (leu:DI (match_operand:DI 1 "register_operand" "d")
6445 (match_operand:DI 2 "small_int" "I")))]
6446 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6447 {
6448 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6449 return "sltu\t%0,%1,%2";
6450 }
6451 [(set_attr "type" "slt")
6452 (set_attr "mode" "DI")])
6453
6454 (define_insn "*sleu_di_mips16"
6455 [(set (match_operand:DI 0 "register_operand" "=t")
6456 (leu:DI (match_operand:DI 1 "register_operand" "d")
6457 (match_operand:DI 2 "small_int" "I")))]
6458 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
6459 {
6460 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6461 return "sltu\t%1,%2";
6462 }
6463 [(set_attr "type" "slt")
6464 (set_attr "mode" "DI")
6465 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
6466 (const_int 4)
6467 (const_int 8)))])
6468 \f
6469 ;;
6470 ;; ....................
6471 ;;
6472 ;; FLOATING POINT COMPARISONS
6473 ;;
6474 ;; ....................
6475
6476 (define_insn "sunordered_df"
6477 [(set (match_operand:CC 0 "register_operand" "=z")
6478 (unordered:CC (match_operand:DF 1 "register_operand" "f")
6479 (match_operand:DF 2 "register_operand" "f")))]
6480 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6481 "c.un.d\t%Z0%1,%2"
6482 [(set_attr "type" "fcmp")
6483 (set_attr "mode" "FPSW")])
6484
6485 (define_insn "sunlt_df"
6486 [(set (match_operand:CC 0 "register_operand" "=z")
6487 (unlt:CC (match_operand:DF 1 "register_operand" "f")
6488 (match_operand:DF 2 "register_operand" "f")))]
6489 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6490 "c.ult.d\t%Z0%1,%2"
6491 [(set_attr "type" "fcmp")
6492 (set_attr "mode" "FPSW")])
6493
6494 (define_insn "suneq_df"
6495 [(set (match_operand:CC 0 "register_operand" "=z")
6496 (uneq:CC (match_operand:DF 1 "register_operand" "f")
6497 (match_operand:DF 2 "register_operand" "f")))]
6498 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6499 "c.ueq.d\t%Z0%1,%2"
6500 [(set_attr "type" "fcmp")
6501 (set_attr "mode" "FPSW")])
6502
6503 (define_insn "sunle_df"
6504 [(set (match_operand:CC 0 "register_operand" "=z")
6505 (unle:CC (match_operand:DF 1 "register_operand" "f")
6506 (match_operand:DF 2 "register_operand" "f")))]
6507 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6508 "c.ule.d\t%Z0%1,%2"
6509 [(set_attr "type" "fcmp")
6510 (set_attr "mode" "FPSW")])
6511
6512 (define_insn "seq_df"
6513 [(set (match_operand:CC 0 "register_operand" "=z")
6514 (eq:CC (match_operand:DF 1 "register_operand" "f")
6515 (match_operand:DF 2 "register_operand" "f")))]
6516 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6517 "c.eq.d\t%Z0%1,%2"
6518 [(set_attr "type" "fcmp")
6519 (set_attr "mode" "FPSW")])
6520
6521 (define_insn "slt_df"
6522 [(set (match_operand:CC 0 "register_operand" "=z")
6523 (lt:CC (match_operand:DF 1 "register_operand" "f")
6524 (match_operand:DF 2 "register_operand" "f")))]
6525 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6526 "c.lt.d\t%Z0%1,%2"
6527 [(set_attr "type" "fcmp")
6528 (set_attr "mode" "FPSW")])
6529
6530 (define_insn "sle_df"
6531 [(set (match_operand:CC 0 "register_operand" "=z")
6532 (le:CC (match_operand:DF 1 "register_operand" "f")
6533 (match_operand:DF 2 "register_operand" "f")))]
6534 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6535 "c.le.d\t%Z0%1,%2"
6536 [(set_attr "type" "fcmp")
6537 (set_attr "mode" "FPSW")])
6538
6539 (define_insn "sgt_df"
6540 [(set (match_operand:CC 0 "register_operand" "=z")
6541 (gt:CC (match_operand:DF 1 "register_operand" "f")
6542 (match_operand:DF 2 "register_operand" "f")))]
6543 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6544 "c.lt.d\t%Z0%2,%1"
6545 [(set_attr "type" "fcmp")
6546 (set_attr "mode" "FPSW")])
6547
6548 (define_insn "sge_df"
6549 [(set (match_operand:CC 0 "register_operand" "=z")
6550 (ge:CC (match_operand:DF 1 "register_operand" "f")
6551 (match_operand:DF 2 "register_operand" "f")))]
6552 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6553 "c.le.d\t%Z0%2,%1"
6554 [(set_attr "type" "fcmp")
6555 (set_attr "mode" "FPSW")])
6556
6557 (define_insn "sunordered_sf"
6558 [(set (match_operand:CC 0 "register_operand" "=z")
6559 (unordered:CC (match_operand:SF 1 "register_operand" "f")
6560 (match_operand:SF 2 "register_operand" "f")))]
6561 "TARGET_HARD_FLOAT"
6562 "c.un.s\t%Z0%1,%2"
6563 [(set_attr "type" "fcmp")
6564 (set_attr "mode" "FPSW")])
6565
6566 (define_insn "sunlt_sf"
6567 [(set (match_operand:CC 0 "register_operand" "=z")
6568 (unlt:CC (match_operand:SF 1 "register_operand" "f")
6569 (match_operand:SF 2 "register_operand" "f")))]
6570 "TARGET_HARD_FLOAT"
6571 "c.ult.s\t%Z0%1,%2"
6572 [(set_attr "type" "fcmp")
6573 (set_attr "mode" "FPSW")])
6574
6575 (define_insn "suneq_sf"
6576 [(set (match_operand:CC 0 "register_operand" "=z")
6577 (uneq:CC (match_operand:SF 1 "register_operand" "f")
6578 (match_operand:SF 2 "register_operand" "f")))]
6579 "TARGET_HARD_FLOAT"
6580 "c.ueq.s\t%Z0%1,%2"
6581 [(set_attr "type" "fcmp")
6582 (set_attr "mode" "FPSW")])
6583
6584 (define_insn "sunle_sf"
6585 [(set (match_operand:CC 0 "register_operand" "=z")
6586 (unle:CC (match_operand:SF 1 "register_operand" "f")
6587 (match_operand:SF 2 "register_operand" "f")))]
6588 "TARGET_HARD_FLOAT"
6589 "c.ule.s\t%Z0%1,%2"
6590 [(set_attr "type" "fcmp")
6591 (set_attr "mode" "FPSW")])
6592
6593 (define_insn "seq_sf"
6594 [(set (match_operand:CC 0 "register_operand" "=z")
6595 (eq:CC (match_operand:SF 1 "register_operand" "f")
6596 (match_operand:SF 2 "register_operand" "f")))]
6597 "TARGET_HARD_FLOAT"
6598 "c.eq.s\t%Z0%1,%2"
6599 [(set_attr "type" "fcmp")
6600 (set_attr "mode" "FPSW")])
6601
6602 (define_insn "slt_sf"
6603 [(set (match_operand:CC 0 "register_operand" "=z")
6604 (lt:CC (match_operand:SF 1 "register_operand" "f")
6605 (match_operand:SF 2 "register_operand" "f")))]
6606 "TARGET_HARD_FLOAT"
6607 "c.lt.s\t%Z0%1,%2"
6608 [(set_attr "type" "fcmp")
6609 (set_attr "mode" "FPSW")])
6610
6611 (define_insn "sle_sf"
6612 [(set (match_operand:CC 0 "register_operand" "=z")
6613 (le:CC (match_operand:SF 1 "register_operand" "f")
6614 (match_operand:SF 2 "register_operand" "f")))]
6615 "TARGET_HARD_FLOAT"
6616 "c.le.s\t%Z0%1,%2"
6617 [(set_attr "type" "fcmp")
6618 (set_attr "mode" "FPSW")])
6619
6620 (define_insn "sgt_sf"
6621 [(set (match_operand:CC 0 "register_operand" "=z")
6622 (gt:CC (match_operand:SF 1 "register_operand" "f")
6623 (match_operand:SF 2 "register_operand" "f")))]
6624 "TARGET_HARD_FLOAT"
6625 "c.lt.s\t%Z0%2,%1"
6626 [(set_attr "type" "fcmp")
6627 (set_attr "mode" "FPSW")])
6628
6629 (define_insn "sge_sf"
6630 [(set (match_operand:CC 0 "register_operand" "=z")
6631 (ge:CC (match_operand:SF 1 "register_operand" "f")
6632 (match_operand:SF 2 "register_operand" "f")))]
6633 "TARGET_HARD_FLOAT"
6634 "c.le.s\t%Z0%2,%1"
6635 [(set_attr "type" "fcmp")
6636 (set_attr "mode" "FPSW")])
6637 \f
6638 ;;
6639 ;; ....................
6640 ;;
6641 ;; UNCONDITIONAL BRANCHES
6642 ;;
6643 ;; ....................
6644
6645 ;; Unconditional branches.
6646
6647 (define_insn "jump"
6648 [(set (pc)
6649 (label_ref (match_operand 0 "" "")))]
6650 "!TARGET_MIPS16"
6651 {
6652 if (flag_pic)
6653 {
6654 if (get_attr_length (insn) <= 8)
6655 return "%*b\t%l0%/";
6656 else
6657 {
6658 output_asm_insn (mips_output_load_label (), operands);
6659 return "%*jr\t%@%/%]";
6660 }
6661 }
6662 else
6663 return "%*j\t%l0%/";
6664 }
6665 [(set_attr "type" "jump")
6666 (set_attr "mode" "none")
6667 (set (attr "length")
6668 ;; We can't use `j' when emitting PIC. Emit a branch if it's
6669 ;; in range, otherwise load the address of the branch target into
6670 ;; $at and then jump to it.
6671 (if_then_else
6672 (ior (eq (symbol_ref "flag_pic") (const_int 0))
6673 (lt (abs (minus (match_dup 0)
6674 (plus (pc) (const_int 4))))
6675 (const_int 131072)))
6676 (const_int 4) (const_int 16)))])
6677
6678 ;; We need a different insn for the mips16, because a mips16 branch
6679 ;; does not have a delay slot.
6680
6681 (define_insn ""
6682 [(set (pc)
6683 (label_ref (match_operand 0 "" "")))]
6684 "TARGET_MIPS16"
6685 "b\t%l0"
6686 [(set_attr "type" "branch")
6687 (set_attr "mode" "none")
6688 (set_attr "length" "8")])
6689
6690 (define_expand "indirect_jump"
6691 [(set (pc) (match_operand 0 "register_operand"))]
6692 ""
6693 {
6694 rtx dest;
6695
6696 dest = operands[0];
6697 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6698 operands[0] = copy_to_mode_reg (Pmode, dest);
6699
6700 if (!(Pmode == DImode))
6701 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6702 else
6703 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6704
6705 DONE;
6706 })
6707
6708 (define_insn "indirect_jump_internal1"
6709 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6710 "!(Pmode == DImode)"
6711 "%*j\t%0%/"
6712 [(set_attr "type" "jump")
6713 (set_attr "mode" "none")])
6714
6715 (define_insn "indirect_jump_internal2"
6716 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
6717 "Pmode == DImode"
6718 "%*j\t%0%/"
6719 [(set_attr "type" "jump")
6720 (set_attr "mode" "none")])
6721
6722 (define_expand "tablejump"
6723 [(set (pc)
6724 (match_operand 0 "register_operand"))
6725 (use (label_ref (match_operand 1 "")))]
6726 ""
6727 {
6728 if (TARGET_MIPS16)
6729 {
6730 if (GET_MODE (operands[0]) != HImode)
6731 abort ();
6732 if (!(Pmode == DImode))
6733 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
6734 else
6735 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
6736 DONE;
6737 }
6738
6739 if (GET_MODE (operands[0]) != ptr_mode)
6740 abort ();
6741
6742 if (TARGET_GPWORD)
6743 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
6744 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
6745
6746 if (Pmode == SImode)
6747 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6748 else
6749 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6750 DONE;
6751 })
6752
6753 (define_insn "tablejump_internal1"
6754 [(set (pc)
6755 (match_operand:SI 0 "register_operand" "d"))
6756 (use (label_ref (match_operand 1 "" "")))]
6757 ""
6758 "%*j\t%0%/"
6759 [(set_attr "type" "jump")
6760 (set_attr "mode" "none")])
6761
6762 (define_insn "tablejump_internal2"
6763 [(set (pc)
6764 (match_operand:DI 0 "register_operand" "d"))
6765 (use (label_ref (match_operand 1 "" "")))]
6766 "TARGET_64BIT"
6767 "%*j\t%0%/"
6768 [(set_attr "type" "jump")
6769 (set_attr "mode" "none")])
6770
6771 (define_expand "tablejump_mips161"
6772 [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
6773 (label_ref:SI (match_operand 1 ""))))]
6774 "TARGET_MIPS16 && !(Pmode == DImode)"
6775 {
6776 rtx t1, t2, t3;
6777
6778 t1 = gen_reg_rtx (SImode);
6779 t2 = gen_reg_rtx (SImode);
6780 t3 = gen_reg_rtx (SImode);
6781 emit_insn (gen_extendhisi2 (t1, operands[0]));
6782 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
6783 emit_insn (gen_addsi3 (t3, t1, t2));
6784 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
6785 DONE;
6786 })
6787
6788 (define_expand "tablejump_mips162"
6789 [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
6790 (label_ref:DI (match_operand 1 ""))))]
6791 "TARGET_MIPS16 && Pmode == DImode"
6792 {
6793 rtx t1, t2, t3;
6794
6795 t1 = gen_reg_rtx (DImode);
6796 t2 = gen_reg_rtx (DImode);
6797 t3 = gen_reg_rtx (DImode);
6798 emit_insn (gen_extendhidi2 (t1, operands[0]));
6799 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
6800 emit_insn (gen_adddi3 (t3, t1, t2));
6801 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
6802 DONE;
6803 })
6804
6805 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
6806 ;; While it is possible to either pull it off the stack (in the
6807 ;; o32 case) or recalculate it given t9 and our target label,
6808 ;; it takes 3 or 4 insns to do so.
6809
6810 (define_expand "builtin_setjmp_setup"
6811 [(use (match_operand 0 "register_operand"))]
6812 "TARGET_ABICALLS"
6813 {
6814 rtx addr;
6815
6816 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
6817 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
6818 DONE;
6819 })
6820
6821 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
6822 ;; that older code did recalculate the gp from $25. Continue to jump through
6823 ;; $25 for compatibility (we lose nothing by doing so).
6824
6825 (define_expand "builtin_longjmp"
6826 [(use (match_operand 0 "register_operand"))]
6827 "TARGET_ABICALLS"
6828 {
6829 /* The elements of the buffer are, in order: */
6830 int W = GET_MODE_SIZE (Pmode);
6831 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6832 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
6833 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
6834 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
6835 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6836 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
6837 The target is bound to be using $28 as the global pointer
6838 but the current function might not be. */
6839 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
6840
6841 /* This bit is similar to expand_builtin_longjmp except that it
6842 restores $gp as well. */
6843 emit_move_insn (hard_frame_pointer_rtx, fp);
6844 emit_move_insn (pv, lab);
6845 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6846 emit_move_insn (gp, gpv);
6847 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6848 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6849 emit_insn (gen_rtx_USE (VOIDmode, gp));
6850 emit_indirect_jump (pv);
6851 DONE;
6852 })
6853 \f
6854 ;;
6855 ;; ....................
6856 ;;
6857 ;; Function prologue/epilogue
6858 ;;
6859 ;; ....................
6860 ;;
6861
6862 (define_expand "prologue"
6863 [(const_int 1)]
6864 ""
6865 {
6866 mips_expand_prologue ();
6867 DONE;
6868 })
6869
6870 ;; Block any insns from being moved before this point, since the
6871 ;; profiling call to mcount can use various registers that aren't
6872 ;; saved or used to pass arguments.
6873
6874 (define_insn "blockage"
6875 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
6876 ""
6877 ""
6878 [(set_attr "type" "unknown")
6879 (set_attr "mode" "none")
6880 (set_attr "length" "0")])
6881
6882 (define_expand "epilogue"
6883 [(const_int 2)]
6884 ""
6885 {
6886 mips_expand_epilogue (false);
6887 DONE;
6888 })
6889
6890 (define_expand "sibcall_epilogue"
6891 [(const_int 2)]
6892 ""
6893 {
6894 mips_expand_epilogue (true);
6895 DONE;
6896 })
6897
6898 ;; Trivial return. Make it look like a normal return insn as that
6899 ;; allows jump optimizations to work better.
6900
6901 (define_insn "return"
6902 [(return)]
6903 "mips_can_use_return_insn ()"
6904 "%*j\t$31%/"
6905 [(set_attr "type" "jump")
6906 (set_attr "mode" "none")])
6907
6908 ;; Normal return.
6909
6910 (define_insn "return_internal"
6911 [(return)
6912 (use (match_operand 0 "pmode_register_operand" ""))]
6913 ""
6914 "%*j\t%0%/"
6915 [(set_attr "type" "jump")
6916 (set_attr "mode" "none")])
6917
6918 ;; This is used in compiling the unwind routines.
6919 (define_expand "eh_return"
6920 [(use (match_operand 0 "general_operand"))]
6921 ""
6922 {
6923 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
6924
6925 if (GET_MODE (operands[0]) != gpr_mode)
6926 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
6927 if (TARGET_64BIT)
6928 emit_insn (gen_eh_set_lr_di (operands[0]));
6929 else
6930 emit_insn (gen_eh_set_lr_si (operands[0]));
6931
6932 DONE;
6933 })
6934
6935 ;; Clobber the return address on the stack. We can't expand this
6936 ;; until we know where it will be put in the stack frame.
6937
6938 (define_insn "eh_set_lr_si"
6939 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6940 (clobber (match_scratch:SI 1 "=&d"))]
6941 "! TARGET_64BIT"
6942 "#")
6943
6944 (define_insn "eh_set_lr_di"
6945 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
6946 (clobber (match_scratch:DI 1 "=&d"))]
6947 "TARGET_64BIT"
6948 "#")
6949
6950 (define_split
6951 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
6952 (clobber (match_scratch 1))]
6953 "reload_completed && !TARGET_DEBUG_D_MODE"
6954 [(const_int 0)]
6955 {
6956 mips_set_return_address (operands[0], operands[1]);
6957 DONE;
6958 })
6959
6960 (define_insn "exception_receiver"
6961 [(set (reg:SI 28)
6962 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
6963 "TARGET_ABICALLS && TARGET_OLDABI"
6964 {
6965 operands[0] = pic_offset_table_rtx;
6966 operands[1] = mips_gp_save_slot ();
6967 return mips_output_move (operands[0], operands[1]);
6968 }
6969 [(set_attr "type" "load")
6970 (set_attr "length" "8")])
6971 \f
6972 ;;
6973 ;; ....................
6974 ;;
6975 ;; FUNCTION CALLS
6976 ;;
6977 ;; ....................
6978
6979 ;; Instructions to load a call address from the GOT. The address might
6980 ;; point to a function or to a lazy binding stub. In the latter case,
6981 ;; the stub will use the dynamic linker to resolve the function, which
6982 ;; in turn will change the GOT entry to point to the function's real
6983 ;; address.
6984 ;;
6985 ;; This means that every call, even pure and constant ones, can
6986 ;; potentially modify the GOT entry. And once a stub has been called,
6987 ;; we must not call it again.
6988 ;;
6989 ;; We represent this restriction using an imaginary fixed register that
6990 ;; acts like a GOT version number. By making the register call-clobbered,
6991 ;; we tell the target-independent code that the address could be changed
6992 ;; by any call insn.
6993 (define_insn "load_callsi"
6994 [(set (match_operand:SI 0 "register_operand" "=c")
6995 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6996 (match_operand:SI 2 "immediate_operand" "")
6997 (reg:SI FAKE_CALL_REGNO)]
6998 UNSPEC_LOAD_CALL))]
6999 "TARGET_ABICALLS"
7000 "lw\t%0,%R2(%1)"
7001 [(set_attr "type" "load")
7002 (set_attr "length" "4")])
7003
7004 (define_insn "load_calldi"
7005 [(set (match_operand:DI 0 "register_operand" "=c")
7006 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7007 (match_operand:DI 2 "immediate_operand" "")
7008 (reg:DI FAKE_CALL_REGNO)]
7009 UNSPEC_LOAD_CALL))]
7010 "TARGET_ABICALLS"
7011 "ld\t%0,%R2(%1)"
7012 [(set_attr "type" "load")
7013 (set_attr "length" "4")])
7014
7015 ;; Sibling calls. All these patterns use jump instructions.
7016
7017 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
7018 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
7019 ;; is defined in terms of call_insn_operand, the same is true of the
7020 ;; constraints.
7021
7022 ;; When we use an indirect jump, we need a register that will be
7023 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
7024 ;; use $25 for this purpose -- and $25 is never clobbered by the
7025 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
7026
7027 (define_expand "sibcall"
7028 [(parallel [(call (match_operand 0 "")
7029 (match_operand 1 ""))
7030 (use (match_operand 2 "")) ;; next_arg_reg
7031 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7032 "TARGET_SIBCALLS"
7033 {
7034 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
7035 DONE;
7036 })
7037
7038 (define_insn "sibcall_internal"
7039 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
7040 (match_operand 1 "" ""))]
7041 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7042 "@
7043 %*jr\t%0%/
7044 %*j\t%0%/"
7045 [(set_attr "type" "call")])
7046
7047 (define_expand "sibcall_value"
7048 [(parallel [(set (match_operand 0 "")
7049 (call (match_operand 1 "")
7050 (match_operand 2 "")))
7051 (use (match_operand 3 ""))])] ;; next_arg_reg
7052 "TARGET_SIBCALLS"
7053 {
7054 mips_expand_call (operands[0], XEXP (operands[1], 0),
7055 operands[2], operands[3], true);
7056 DONE;
7057 })
7058
7059 (define_insn "sibcall_value_internal"
7060 [(set (match_operand 0 "register_operand" "=df,df")
7061 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7062 (match_operand 2 "" "")))]
7063 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7064 "@
7065 %*jr\t%1%/
7066 %*j\t%1%/"
7067 [(set_attr "type" "call")])
7068
7069 (define_insn "sibcall_value_multiple_internal"
7070 [(set (match_operand 0 "register_operand" "=df,df")
7071 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
7072 (match_operand 2 "" "")))
7073 (set (match_operand 3 "register_operand" "=df,df")
7074 (call (mem:SI (match_dup 1))
7075 (match_dup 2)))]
7076 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
7077 "@
7078 %*jr\t%1%/
7079 %*j\t%1%/"
7080 [(set_attr "type" "call")])
7081
7082 (define_expand "call"
7083 [(parallel [(call (match_operand 0 "")
7084 (match_operand 1 ""))
7085 (use (match_operand 2 "")) ;; next_arg_reg
7086 (use (match_operand 3 ""))])] ;; struct_value_size_rtx
7087 ""
7088 {
7089 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
7090 DONE;
7091 })
7092
7093 ;; This instruction directly corresponds to an assembly-language "jal".
7094 ;; There are four cases:
7095 ;;
7096 ;; - -mno-abicalls:
7097 ;; Both symbolic and register destinations are OK. The pattern
7098 ;; always expands to a single mips instruction.
7099 ;;
7100 ;; - -mabicalls/-mno-explicit-relocs:
7101 ;; Again, both symbolic and register destinations are OK.
7102 ;; The call is treated as a multi-instruction black box.
7103 ;;
7104 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
7105 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
7106 ;; instruction.
7107 ;;
7108 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
7109 ;; Only "jal $25" is allowed. The call is actually two instructions:
7110 ;; "jalr $25" followed by an insn to reload $gp.
7111 ;;
7112 ;; In the last case, we can generate the individual instructions with
7113 ;; a define_split. There are several things to be wary of:
7114 ;;
7115 ;; - We can't expose the load of $gp before reload. If we did,
7116 ;; it might get removed as dead, but reload can introduce new
7117 ;; uses of $gp by rematerializing constants.
7118 ;;
7119 ;; - We shouldn't restore $gp after calls that never return.
7120 ;; It isn't valid to insert instructions between a noreturn
7121 ;; call and the following barrier.
7122 ;;
7123 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
7124 ;; instruction preserves $gp and so have no effect on its liveness.
7125 ;; But once we generate the separate insns, it becomes obvious that
7126 ;; $gp is not live on entry to the call.
7127 ;;
7128 ;; ??? The operands[2] = insn check is a hack to make the original insn
7129 ;; available to the splitter.
7130 (define_insn_and_split "call_internal"
7131 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
7132 (match_operand 1 "" ""))
7133 (clobber (reg:SI 31))]
7134 ""
7135 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
7136 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
7137 [(const_int 0)]
7138 {
7139 emit_call_insn (gen_call_split (operands[0], operands[1]));
7140 if (!find_reg_note (operands[2], REG_NORETURN, 0))
7141 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7142 DONE;
7143 }
7144 [(set_attr "jal" "indirect,direct")
7145 (set_attr "extended_mips16" "no,yes")])
7146
7147 (define_insn "call_split"
7148 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
7149 (match_operand 1 "" ""))
7150 (clobber (reg:SI 31))
7151 (clobber (reg:SI 28))]
7152 "TARGET_SPLIT_CALLS"
7153 "%*jalr\t%0%/"
7154 [(set_attr "type" "call")])
7155
7156 (define_expand "call_value"
7157 [(parallel [(set (match_operand 0 "")
7158 (call (match_operand 1 "")
7159 (match_operand 2 "")))
7160 (use (match_operand 3 ""))])] ;; next_arg_reg
7161 ""
7162 {
7163 mips_expand_call (operands[0], XEXP (operands[1], 0),
7164 operands[2], operands[3], false);
7165 DONE;
7166 })
7167
7168 ;; See comment for call_internal.
7169 (define_insn_and_split "call_value_internal"
7170 [(set (match_operand 0 "register_operand" "=df,df")
7171 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7172 (match_operand 2 "" "")))
7173 (clobber (reg:SI 31))]
7174 ""
7175 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7176 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
7177 [(const_int 0)]
7178 {
7179 emit_call_insn (gen_call_value_split (operands[0], operands[1],
7180 operands[2]));
7181 if (!find_reg_note (operands[3], REG_NORETURN, 0))
7182 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7183 DONE;
7184 }
7185 [(set_attr "jal" "indirect,direct")
7186 (set_attr "extended_mips16" "no,yes")])
7187
7188 (define_insn "call_value_split"
7189 [(set (match_operand 0 "register_operand" "=df")
7190 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7191 (match_operand 2 "" "")))
7192 (clobber (reg:SI 31))
7193 (clobber (reg:SI 28))]
7194 "TARGET_SPLIT_CALLS"
7195 "%*jalr\t%1%/"
7196 [(set_attr "type" "call")])
7197
7198 ;; See comment for call_internal.
7199 (define_insn_and_split "call_value_multiple_internal"
7200 [(set (match_operand 0 "register_operand" "=df,df")
7201 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
7202 (match_operand 2 "" "")))
7203 (set (match_operand 3 "register_operand" "=df,df")
7204 (call (mem:SI (match_dup 1))
7205 (match_dup 2)))
7206 (clobber (reg:SI 31))]
7207 ""
7208 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
7209 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
7210 [(const_int 0)]
7211 {
7212 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
7213 operands[2], operands[3]));
7214 if (!find_reg_note (operands[4], REG_NORETURN, 0))
7215 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
7216 DONE;
7217 }
7218 [(set_attr "jal" "indirect,direct")
7219 (set_attr "extended_mips16" "no,yes")])
7220
7221 (define_insn "call_value_multiple_split"
7222 [(set (match_operand 0 "register_operand" "=df")
7223 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
7224 (match_operand 2 "" "")))
7225 (set (match_operand 3 "register_operand" "=df")
7226 (call (mem:SI (match_dup 1))
7227 (match_dup 2)))
7228 (clobber (reg:SI 31))
7229 (clobber (reg:SI 28))]
7230 "TARGET_SPLIT_CALLS"
7231 "%*jalr\t%1%/"
7232 [(set_attr "type" "call")])
7233
7234 ;; Call subroutine returning any type.
7235
7236 (define_expand "untyped_call"
7237 [(parallel [(call (match_operand 0 "")
7238 (const_int 0))
7239 (match_operand 1 "")
7240 (match_operand 2 "")])]
7241 ""
7242 {
7243 int i;
7244
7245 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7246
7247 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7248 {
7249 rtx set = XVECEXP (operands[2], 0, i);
7250 emit_move_insn (SET_DEST (set), SET_SRC (set));
7251 }
7252
7253 emit_insn (gen_blockage ());
7254 DONE;
7255 })
7256 \f
7257 ;;
7258 ;; ....................
7259 ;;
7260 ;; MISC.
7261 ;;
7262 ;; ....................
7263 ;;
7264
7265
7266 (define_expand "prefetch"
7267 [(prefetch (match_operand 0 "address_operand")
7268 (match_operand 1 "const_int_operand")
7269 (match_operand 2 "const_int_operand"))]
7270 "ISA_HAS_PREFETCH"
7271 {
7272 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
7273 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
7274 })
7275
7276 (define_insn "prefetch_si_address"
7277 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7278 (match_operand:SI 3 "const_int_operand" "I"))
7279 (match_operand:SI 1 "const_int_operand" "n")
7280 (match_operand:SI 2 "const_int_operand" "n"))]
7281 "ISA_HAS_PREFETCH && Pmode == SImode"
7282 { return mips_emit_prefetch (operands); }
7283 [(set_attr "type" "prefetch")])
7284
7285 (define_insn "prefetch_indexed_si"
7286 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
7287 (match_operand:SI 3 "register_operand" "r"))
7288 (match_operand:SI 1 "const_int_operand" "n")
7289 (match_operand:SI 2 "const_int_operand" "n"))]
7290 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
7291 { return mips_emit_prefetch (operands); }
7292 [(set_attr "type" "prefetchx")])
7293
7294 (define_insn "prefetch_si"
7295 [(prefetch (match_operand:SI 0 "register_operand" "r")
7296 (match_operand:SI 1 "const_int_operand" "n")
7297 (match_operand:SI 2 "const_int_operand" "n"))]
7298 "ISA_HAS_PREFETCH && Pmode == SImode"
7299 {
7300 operands[3] = const0_rtx;
7301 return mips_emit_prefetch (operands);
7302 }
7303 [(set_attr "type" "prefetch")])
7304
7305 (define_insn "prefetch_di_address"
7306 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7307 (match_operand:DI 3 "const_int_operand" "I"))
7308 (match_operand:DI 1 "const_int_operand" "n")
7309 (match_operand:DI 2 "const_int_operand" "n"))]
7310 "ISA_HAS_PREFETCH && Pmode == DImode"
7311 { return mips_emit_prefetch (operands); }
7312 [(set_attr "type" "prefetch")])
7313
7314 (define_insn "prefetch_indexed_di"
7315 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
7316 (match_operand:DI 3 "register_operand" "r"))
7317 (match_operand:DI 1 "const_int_operand" "n")
7318 (match_operand:DI 2 "const_int_operand" "n"))]
7319 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
7320 { return mips_emit_prefetch (operands); }
7321 [(set_attr "type" "prefetchx")])
7322
7323 (define_insn "prefetch_di"
7324 [(prefetch (match_operand:DI 0 "register_operand" "r")
7325 (match_operand:DI 1 "const_int_operand" "n")
7326 (match_operand:DI 2 "const_int_operand" "n"))]
7327 "ISA_HAS_PREFETCH && Pmode == DImode"
7328 {
7329 operands[3] = const0_rtx;
7330 return mips_emit_prefetch (operands);
7331 }
7332 [(set_attr "type" "prefetch")])
7333
7334 (define_insn "nop"
7335 [(const_int 0)]
7336 ""
7337 "%(nop%)"
7338 [(set_attr "type" "nop")
7339 (set_attr "mode" "none")])
7340
7341 ;; Like nop, but commented out when outside a .set noreorder block.
7342 (define_insn "hazard_nop"
7343 [(const_int 1)]
7344 ""
7345 {
7346 if (set_noreorder)
7347 return "nop";
7348 else
7349 return "#nop";
7350 }
7351 [(set_attr "type" "nop")])
7352 \f
7353 ;; MIPS4 Conditional move instructions.
7354
7355 (define_insn ""
7356 [(set (match_operand:SI 0 "register_operand" "=d,d")
7357 (if_then_else:SI
7358 (match_operator 4 "equality_op"
7359 [(match_operand:SI 1 "register_operand" "d,d")
7360 (const_int 0)])
7361 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7362 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7363 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7364 "@
7365 mov%B4\t%0,%z2,%1
7366 mov%b4\t%0,%z3,%1"
7367 [(set_attr "type" "condmove")
7368 (set_attr "mode" "SI")])
7369
7370 (define_insn ""
7371 [(set (match_operand:SI 0 "register_operand" "=d,d")
7372 (if_then_else:SI
7373 (match_operator 4 "equality_op"
7374 [(match_operand:DI 1 "register_operand" "d,d")
7375 (const_int 0)])
7376 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7377 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7378 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7379 "@
7380 mov%B4\t%0,%z2,%1
7381 mov%b4\t%0,%z3,%1"
7382 [(set_attr "type" "condmove")
7383 (set_attr "mode" "SI")])
7384
7385 (define_insn ""
7386 [(set (match_operand:SI 0 "register_operand" "=d,d")
7387 (if_then_else:SI
7388 (match_operator 3 "equality_op" [(match_operand:CC 4
7389 "register_operand"
7390 "z,z")
7391 (const_int 0)])
7392 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7393 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7394 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7395 "@
7396 mov%T3\t%0,%z1,%4
7397 mov%t3\t%0,%z2,%4"
7398 [(set_attr "type" "condmove")
7399 (set_attr "mode" "SI")])
7400
7401 (define_insn ""
7402 [(set (match_operand:DI 0 "register_operand" "=d,d")
7403 (if_then_else:DI
7404 (match_operator 4 "equality_op"
7405 [(match_operand:SI 1 "register_operand" "d,d")
7406 (const_int 0)])
7407 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7408 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7409 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7410 "@
7411 mov%B4\t%0,%z2,%1
7412 mov%b4\t%0,%z3,%1"
7413 [(set_attr "type" "condmove")
7414 (set_attr "mode" "DI")])
7415
7416 (define_insn ""
7417 [(set (match_operand:DI 0 "register_operand" "=d,d")
7418 (if_then_else:DI
7419 (match_operator 4 "equality_op"
7420 [(match_operand:DI 1 "register_operand" "d,d")
7421 (const_int 0)])
7422 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
7423 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
7424 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7425 "@
7426 mov%B4\t%0,%z2,%1
7427 mov%b4\t%0,%z3,%1"
7428 [(set_attr "type" "condmove")
7429 (set_attr "mode" "DI")])
7430
7431 (define_insn ""
7432 [(set (match_operand:DI 0 "register_operand" "=d,d")
7433 (if_then_else:DI
7434 (match_operator 3 "equality_op" [(match_operand:CC 4
7435 "register_operand"
7436 "z,z")
7437 (const_int 0)])
7438 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
7439 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
7440 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
7441 "@
7442 mov%T3\t%0,%z1,%4
7443 mov%t3\t%0,%z2,%4"
7444 [(set_attr "type" "condmove")
7445 (set_attr "mode" "DI")])
7446
7447 (define_insn ""
7448 [(set (match_operand:SF 0 "register_operand" "=f,f")
7449 (if_then_else:SF
7450 (match_operator 4 "equality_op"
7451 [(match_operand:SI 1 "register_operand" "d,d")
7452 (const_int 0)])
7453 (match_operand:SF 2 "register_operand" "f,0")
7454 (match_operand:SF 3 "register_operand" "0,f")))]
7455 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7456 "@
7457 mov%B4.s\t%0,%2,%1
7458 mov%b4.s\t%0,%3,%1"
7459 [(set_attr "type" "condmove")
7460 (set_attr "mode" "SF")])
7461
7462 (define_insn ""
7463 [(set (match_operand:SF 0 "register_operand" "=f,f")
7464 (if_then_else:SF
7465 (match_operator 4 "equality_op"
7466 [(match_operand:DI 1 "register_operand" "d,d")
7467 (const_int 0)])
7468 (match_operand:SF 2 "register_operand" "f,0")
7469 (match_operand:SF 3 "register_operand" "0,f")))]
7470 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7471 "@
7472 mov%B4.s\t%0,%2,%1
7473 mov%b4.s\t%0,%3,%1"
7474 [(set_attr "type" "condmove")
7475 (set_attr "mode" "SF")])
7476
7477 (define_insn ""
7478 [(set (match_operand:SF 0 "register_operand" "=f,f")
7479 (if_then_else:SF
7480 (match_operator 3 "equality_op" [(match_operand:CC 4
7481 "register_operand"
7482 "z,z")
7483 (const_int 0)])
7484 (match_operand:SF 1 "register_operand" "f,0")
7485 (match_operand:SF 2 "register_operand" "0,f")))]
7486 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7487 "@
7488 mov%T3.s\t%0,%1,%4
7489 mov%t3.s\t%0,%2,%4"
7490 [(set_attr "type" "condmove")
7491 (set_attr "mode" "SF")])
7492
7493 (define_insn ""
7494 [(set (match_operand:DF 0 "register_operand" "=f,f")
7495 (if_then_else:DF
7496 (match_operator 4 "equality_op"
7497 [(match_operand:SI 1 "register_operand" "d,d")
7498 (const_int 0)])
7499 (match_operand:DF 2 "register_operand" "f,0")
7500 (match_operand:DF 3 "register_operand" "0,f")))]
7501 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7502 "@
7503 mov%B4.d\t%0,%2,%1
7504 mov%b4.d\t%0,%3,%1"
7505 [(set_attr "type" "condmove")
7506 (set_attr "mode" "DF")])
7507
7508 (define_insn ""
7509 [(set (match_operand:DF 0 "register_operand" "=f,f")
7510 (if_then_else:DF
7511 (match_operator 4 "equality_op"
7512 [(match_operand:DI 1 "register_operand" "d,d")
7513 (const_int 0)])
7514 (match_operand:DF 2 "register_operand" "f,0")
7515 (match_operand:DF 3 "register_operand" "0,f")))]
7516 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7517 "@
7518 mov%B4.d\t%0,%2,%1
7519 mov%b4.d\t%0,%3,%1"
7520 [(set_attr "type" "condmove")
7521 (set_attr "mode" "DF")])
7522
7523 (define_insn ""
7524 [(set (match_operand:DF 0 "register_operand" "=f,f")
7525 (if_then_else:DF
7526 (match_operator 3 "equality_op" [(match_operand:CC 4
7527 "register_operand"
7528 "z,z")
7529 (const_int 0)])
7530 (match_operand:DF 1 "register_operand" "f,0")
7531 (match_operand:DF 2 "register_operand" "0,f")))]
7532 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7533 "@
7534 mov%T3.d\t%0,%1,%4
7535 mov%t3.d\t%0,%2,%4"
7536 [(set_attr "type" "condmove")
7537 (set_attr "mode" "DF")])
7538
7539 ;; These are the main define_expand's used to make conditional moves.
7540
7541 (define_expand "movsicc"
7542 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7543 (set (match_operand:SI 0 "register_operand")
7544 (if_then_else:SI (match_dup 5)
7545 (match_operand:SI 2 "reg_or_0_operand")
7546 (match_operand:SI 3 "reg_or_0_operand")))]
7547 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
7548 {
7549 gen_conditional_move (operands);
7550 DONE;
7551 })
7552
7553 (define_expand "movdicc"
7554 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7555 (set (match_operand:DI 0 "register_operand")
7556 (if_then_else:DI (match_dup 5)
7557 (match_operand:DI 2 "reg_or_0_operand")
7558 (match_operand:DI 3 "reg_or_0_operand")))]
7559 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
7560 {
7561 gen_conditional_move (operands);
7562 DONE;
7563 })
7564
7565 (define_expand "movsfcc"
7566 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7567 (set (match_operand:SF 0 "register_operand")
7568 (if_then_else:SF (match_dup 5)
7569 (match_operand:SF 2 "register_operand")
7570 (match_operand:SF 3 "register_operand")))]
7571 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
7572 {
7573 gen_conditional_move (operands);
7574 DONE;
7575 })
7576
7577 (define_expand "movdfcc"
7578 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
7579 (set (match_operand:DF 0 "register_operand")
7580 (if_then_else:DF (match_dup 5)
7581 (match_operand:DF 2 "register_operand")
7582 (match_operand:DF 3 "register_operand")))]
7583 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7584 {
7585 gen_conditional_move (operands);
7586 DONE;
7587 })
7588 \f
7589 ;;
7590 ;; ....................
7591 ;;
7592 ;; mips16 inline constant tables
7593 ;;
7594 ;; ....................
7595 ;;
7596
7597 (define_insn "consttable_int"
7598 [(unspec_volatile [(match_operand 0 "consttable_operand" "")
7599 (match_operand 1 "const_int_operand" "")]
7600 UNSPEC_CONSTTABLE_INT)]
7601 "TARGET_MIPS16"
7602 {
7603 assemble_integer (operands[0], INTVAL (operands[1]),
7604 BITS_PER_UNIT * INTVAL (operands[1]), 1);
7605 return "";
7606 }
7607 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
7608
7609 (define_insn "consttable_float"
7610 [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
7611 UNSPEC_CONSTTABLE_FLOAT)]
7612 "TARGET_MIPS16"
7613 {
7614 REAL_VALUE_TYPE d;
7615
7616 if (GET_CODE (operands[0]) != CONST_DOUBLE)
7617 abort ();
7618 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7619 assemble_real (d, GET_MODE (operands[0]),
7620 GET_MODE_BITSIZE (GET_MODE (operands[0])));
7621 return "";
7622 }
7623 [(set (attr "length")
7624 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
7625
7626 (define_insn "align"
7627 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
7628 ""
7629 ".align\t%0"
7630 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
7631 \f
7632 (define_split
7633 [(match_operand 0 "small_data_pattern")]
7634 "reload_completed"
7635 [(match_dup 0)]
7636 { operands[0] = mips_rewrite_small_data (operands[0]); })