]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/mips/mips.md
Merge from rewrite branch.
[thirdparty/gcc.git] / gcc / config / mips / mips.md
CommitLineData
8ef30996 1;; Mips.md Machine Description for MIPS based processors
214be03f 2;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
2d2a50c3 3;; 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
8ef30996
MM
4;; Contributed by A. Lichnewsky, lich@inria.inria.fr
5;; Changes by Michael Meissner, meissner@osf.org
bb621ad7
JW
6;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7;; Brendan Eich, brendan@microunity.com.
8ef30996
MM
8
9;; This file is part of GNU CC.
10
11;; GNU CC 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;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
3f63df56
RK
23;; the Free Software Foundation, 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
8ef30996 25
e19ff60f
JW
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
41f8d041 29(define_constants
cafe096b 30 [(UNSPEC_GET_FNADDR 4)
41f8d041
RS
31 (UNSPEC_HILO_DELAY 5)
32 (UNSPEC_BLOCKAGE 6)
33 (UNSPEC_LOADGP 7)
34 (UNSPEC_SETJMP 8)
35 (UNSPEC_LONGJMP 9)
36 (UNSPEC_EH_RECEIVER 10)
37 (UNSPEC_EH_RETURN 11)
38 (UNSPEC_CONSTTABLE_QI 12)
39 (UNSPEC_CONSTTABLE_HI 13)
40 (UNSPEC_CONSTTABLE_SI 14)
41 (UNSPEC_CONSTTABLE_DI 15)
42 (UNSPEC_CONSTTABLE_SF 16)
43 (UNSPEC_CONSTTABLE_DF 17)
44 (UNSPEC_ALIGN_2 18)
45 (UNSPEC_ALIGN_4 19)
cafe096b
EC
46 (UNSPEC_ALIGN_8 20)
47 (UNSPEC_HIGH 22)
48 (UNSPEC_LWL 23)
49 (UNSPEC_LWR 24)
50 (UNSPEC_SWL 25)
51 (UNSPEC_SWR 26)
52 (UNSPEC_LDL 27)
53 (UNSPEC_LDR 28)
54 (UNSPEC_SDL 29)
55 (UNSPEC_SDR 30)
56
57 ;; Constants used in relocation unspecs. RELOC_GOT_PAGE and RELOC_GOT_DISP
58 ;; are really only available for n32 and n64. However, it is convenient
59 ;; to reuse them for SVR4 PIC, where they represent the local and global
60 ;; forms of R_MIPS_GOT16.
61 (RELOC_GPREL16 100)
62 (RELOC_GOT_HI 101)
63 (RELOC_GOT_LO 102)
64 (RELOC_GOT_PAGE 103)
65 (RELOC_GOT_DISP 104)
66 (RELOC_CALL16 105)
67 (RELOC_CALL_HI 106)
68 (RELOC_CALL_LO 107)])
8ef30996
MM
69\f
70
71;; ....................
72;;
73;; Attributes
74;;
75;; ....................
76
cafe096b
EC
77;; For jal instructions, this attribute is DIRECT when the target address
78;; is symbolic and INDIRECT when it is a register.
79(define_attr "jal" "unset,direct,indirect"
80 (const_string "unset"))
81
82;; True for multi-instruction jal macros. jal is always a macro
83;; in SVR4 PIC since it includes an instruction to restore $gp.
84;; Direct jals are also macros in NewABI PIC since they load the
85;; target address into $25.
86(define_attr "jal_macro" "no,yes"
87 (cond [(eq_attr "jal" "direct")
88 (symbol_ref "TARGET_ABICALLS != 0")
89 (eq_attr "jal" "indirect")
90 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
91 (const_string "no")))
92
8ef30996
MM
93;; Classification of each insn.
94;; branch conditional branch
95;; jump unconditional jump
96;; call unconditional call
97;; load load instruction(s)
98;; store store instruction(s)
cafe096b 99;; prefetch memory prefetch
8ef30996
MM
100;; move data movement within same register set
101;; xfer transfer to/from coprocessor
102;; hilo transfer of hi/lo registers
103;; arith integer arithmetic instruction
104;; darith double precision integer arithmetic instructions
cafe096b 105;; const load constant
8ef30996 106;; imul integer multiply
1d4047e0 107;; imadd integer multiply-add
8ef30996
MM
108;; idiv integer divide
109;; icmp integer compare
110;; fadd floating point add/subtract
111;; fmul floating point multiply
e19ff60f 112;; fmadd floating point multiply-add
8ef30996
MM
113;; fdiv floating point divide
114;; fabs floating point absolute value
115;; fneg floating point negation
116;; fcmp floating point compare
117;; fcvt floating point convert
118;; fsqrt floating point square root
5ce6f47b 119;; frsqrt floating point reciprocal square root
8ef30996
MM
120;; multi multiword sequence (or user asm statements)
121;; nop no operation
8ef30996 122(define_attr "type"
cafe096b
EC
123 "unknown,branch,jump,call,load,store,prefetch,move,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
124 (cond [(eq_attr "jal" "!unset")
125 (const_string "call")]
126 (const_string "unknown")))
8ef30996
MM
127
128;; Main data type used by the insn
34b650b3 129(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
8ef30996 130
cafe096b
EC
131;; Is this an extended instruction in mips16 mode?
132(define_attr "extended_mips16" "no,yes"
133 (const_string "no"))
134
0ff83799
MM
135;; Length (in # of bytes). A conditional branch is allowed only to a
136;; location within a signed 18-bit offset of the delay slot. If that
137;; provides too smal a range, we use the `j' instruction. This
138;; instruction takes a 28-bit value, but that value is not an offset.
139;; Instead, it's bitwise-ored with the high-order four bits of the
140;; instruction in the delay slot, which means it cannot be used to
141;; cross a 256MB boundary. We could fall back back on the jr,
142;; instruction which allows full access to the entire address space,
143;; but we do not do so at present.
144
7a38df19 145(define_attr "length" ""
0ff83799
MM
146 (cond [(eq_attr "type" "branch")
147 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
148 (const_int 131072))
852dff61
AO
149 (const_int 4)
150 (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
151 (const_int 0))
152 (const_int 24)
153 ] (const_int 12))
cafe096b
EC
154 (eq_attr "type" "const")
155 (symbol_ref "mips_const_insns (operands[1]) * 4")
156 (eq_attr "type" "load")
157 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
158 (eq_attr "type" "store")
159 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
160 ;; In the worst case, a call macro will take 8 instructions:
161 ;;
162 ;; lui $25,%call_hi(FOO)
163 ;; addu $25,$25,$28
164 ;; lw $25,%call_lo(FOO)($25)
165 ;; nop
166 ;; jalr $25
167 ;; nop
168 ;; lw $gp,X($sp)
169 ;; nop
170 (eq_attr "jal_macro" "yes")
171 (const_int 32)
172 (and (eq_attr "extended_mips16" "yes")
173 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
174 (const_int 8)
852dff61 175 ] (const_int 4)))
8ef30996 176
ddd8ab48
MM
177;; Attribute describing the processor. This attribute must match exactly
178;; with the processor_type enumeration in mips.h.
179
8ef30996 180;; Attribute describing the processor
ddd8ab48
MM
181;; (define_attr "cpu" "default,r3000,r6000,r4000"
182;; (const
183;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
184;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
185;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
186;; (const_string "default"))))
187
e19ff60f 188;; ??? Fix everything that tests this attribute.
b8eb88d0 189(define_attr "cpu"
fcc11c35 190 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sb1,sr71000"
ddd8ab48 191 (const (symbol_ref "mips_cpu_attr")))
8ef30996 192
ec350bdd 193;; Does the instruction have a mandatory delay slot?
0ff83799 194;; The 3900, is (mostly) mips1, but does not have a mandatory load delay
7a38df19 195;; slot.
ec350bdd
GK
196(define_attr "dslot" "no,yes"
197 (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
198 (and (eq_attr "type" "load")
199 (and (eq (symbol_ref "mips_isa") (const_int 1))
200 (and (eq (symbol_ref "mips16") (const_int 0))
201 (eq_attr "cpu" "!r3900")))))
202 (const_string "yes")
203 (const_string "no")))
204
cafe096b
EC
205;; Is it a single instruction?
206(define_attr "single_insn" "no,yes"
207 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
208
f1ba94dd
RH
209;; Can the instruction be put into a delay slot?
210(define_attr "can_delay" "no,yes"
211 (if_then_else (and (eq_attr "dslot" "no")
cafe096b 212 (eq_attr "single_insn" "yes"))
f1ba94dd
RH
213 (const_string "yes")
214 (const_string "no")))
215
8ef30996 216;; Attribute defining whether or not we can use the branch-likely instructions
8ef30996
MM
217
218(define_attr "branch_likely" "no,yes"
6d518002 219 (const
e9a25f70 220 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
8ef30996 221 (const_string "yes")
6d518002 222 (const_string "no"))))
8ef30996
MM
223
224
225;; Describe a user's asm statement.
226(define_asm_attributes
227 [(set_attr "type" "multi")])
228
229\f
230
231;; .........................
232;;
233;; Delay slots, can't describe load/fcmp/xfer delay slots here
234;;
235;; .........................
236
2bcb2ab3
GK
237(define_delay (and (eq_attr "type" "branch")
238 (eq (symbol_ref "mips16") (const_int 0)))
f1ba94dd 239 [(eq_attr "can_delay" "yes")
8ef30996 240 (nil)
06e455a9 241 (and (eq_attr "branch_likely" "yes")
cafe096b 242 (eq_attr "can_delay" "yes"))])
8ef30996 243
84a92af4 244(define_delay (eq_attr "type" "jump")
f1ba94dd 245 [(eq_attr "can_delay" "yes")
84a92af4
JW
246 (nil)
247 (nil)])
248
cafe096b
EC
249(define_delay (and (eq_attr "type" "call")
250 (eq_attr "jal_macro" "no"))
f1ba94dd 251 [(eq_attr "can_delay" "yes")
8ef30996
MM
252 (nil)
253 (nil)])
254
255\f
256
257;; .........................
258;;
259;; Functional units
260;;
261;; .........................
262
263; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
c8e18a2b 264; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
8ef30996
MM
265
266;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
267
268(define_function_unit "memory" 1 0
b8eb88d0 269 (and (eq_attr "type" "load")
3f7967e3 270 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
8ef30996
MM
271 3 0)
272
273(define_function_unit "memory" 1 0
b8eb88d0 274 (and (eq_attr "type" "load")
3f7967e3 275 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
8ef30996
MM
276 2 0)
277
ddd8ab48 278(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
8ef30996 279
c3f3d7e1 280(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
8ef30996 281
bb621ad7
JW
282(define_function_unit "imuldiv" 1 0
283 (eq_attr "type" "hilo")
284 1 3)
285
286(define_function_unit "imuldiv" 1 0
1d4047e0 287 (and (eq_attr "type" "imul,imadd")
3f7967e3 288 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
bb621ad7 289 17 17)
8ef30996 290
2bcb2ab3
GK
291;; On them mips16, we want to stronly discourage a mult from appearing
292;; after an mflo, since that requires explicit nop instructions. We
293;; do this by pretending that mflo ties up the function unit for long
294;; enough that the scheduler will ignore load stalls and the like when
295;; selecting instructions to between the two instructions.
296
297(define_function_unit "imuldiv" 1 0
298 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
299 1 5)
300
bb621ad7 301(define_function_unit "imuldiv" 1 0
1d4047e0 302 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
bb621ad7 303 12 12)
8ef30996 304
bb621ad7 305(define_function_unit "imuldiv" 1 0
1d4047e0 306 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
bb621ad7 307 10 10)
8ef30996 308
bb621ad7 309(define_function_unit "imuldiv" 1 0
1d4047e0 310 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
053665d7
ILT
311 4 4)
312
313(define_function_unit "imuldiv" 1 0
1d4047e0 314 (and (eq_attr "type" "imul,imadd")
3f7967e3 315 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
8fbaea49
JW
316 1 1)
317
318(define_function_unit "imuldiv" 1 0
1d4047e0 319 (and (eq_attr "type" "imul,imadd")
3f7967e3 320 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
8fbaea49
JW
321 4 4)
322
323(define_function_unit "imuldiv" 1 0
1d4047e0 324 (and (eq_attr "type" "imul,imadd")
41f9efba 325 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
8fbaea49
JW
326 5 5)
327
328(define_function_unit "imuldiv" 1 0
1d4047e0 329 (and (eq_attr "type" "imul,imadd")
41f9efba 330 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
8fbaea49
JW
331 8 8)
332
333(define_function_unit "imuldiv" 1 0
1d4047e0 334 (and (eq_attr "type" "imul,imadd")
b8eb88d0
ILT
335 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
336 9 9)
337
338(define_function_unit "imuldiv" 1 0
339 (and (eq_attr "type" "idiv")
3f7967e3 340 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
bb621ad7 341 38 38)
8ef30996 342
bb621ad7 343(define_function_unit "imuldiv" 1 0
e9a25f70 344 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
bb621ad7
JW
345 35 35)
346
347(define_function_unit "imuldiv" 1 0
348 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
349 42 42)
8ef30996 350
053665d7
ILT
351(define_function_unit "imuldiv" 1 0
352 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
353 36 36)
354
bb621ad7 355(define_function_unit "imuldiv" 1 0
8ef30996 356 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
bb621ad7
JW
357 69 69)
358
8fbaea49 359(define_function_unit "imuldiv" 1 0
b8eb88d0 360 (and (eq_attr "type" "idiv")
3f7967e3 361 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
8fbaea49
JW
362 35 35)
363
364(define_function_unit "imuldiv" 1 0
b8eb88d0 365 (and (eq_attr "type" "idiv")
3f7967e3 366 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
8fbaea49
JW
367 67 67)
368
369(define_function_unit "imuldiv" 1 0
b8eb88d0 370 (and (eq_attr "type" "idiv")
41f9efba 371 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
8fbaea49
JW
372 37 37)
373
374(define_function_unit "imuldiv" 1 0
b8eb88d0 375 (and (eq_attr "type" "idiv")
41f9efba 376 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
8fbaea49
JW
377 69 69)
378
b8eb88d0
ILT
379(define_function_unit "imuldiv" 1 0
380 (and (eq_attr "type" "idiv")
381 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
382 36 36)
383
384(define_function_unit "imuldiv" 1 0
385 (and (eq_attr "type" "idiv")
386 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
387 68 68)
388
956d6950 389;; The R4300 does *NOT* have a separate Floating Point Unit, instead
8fbaea49
JW
390;; the FP hardware is part of the normal ALU circuitry. This means FP
391;; instructions affect the pipe-line, and no functional unit
392;; parallelism can occur on R4300 processors. To force GCC into coding
393;; for only a single functional unit, we force the R4300 FP
394;; instructions to be processed in the "imuldiv" unit.
395
bb621ad7 396(define_function_unit "adder" 1 1
41f9efba 397 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
bb621ad7
JW
398 3 0)
399
400(define_function_unit "adder" 1 1
e9a25f70 401 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
bb621ad7 402 2 0)
8ef30996 403
b8eb88d0
ILT
404(define_function_unit "adder" 1 1
405 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
406 1 0)
407
8ef30996 408(define_function_unit "adder" 1 1
41f9efba 409 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
c8e18a2b 410 4 0)
8ef30996
MM
411
412(define_function_unit "adder" 1 1
e9a25f70 413 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
c8e18a2b 414 2 0)
8ef30996
MM
415
416(define_function_unit "adder" 1 1
417 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
c8e18a2b 418 3 0)
8ef30996 419
ddd8ab48 420(define_function_unit "adder" 1 1
b8eb88d0 421 (and (eq_attr "type" "fabs,fneg")
41f9efba 422 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
c8e18a2b 423 2 0)
8ef30996 424
ddd8ab48 425(define_function_unit "adder" 1 1
e9a25f70 426 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
c8e18a2b 427 1 0)
8ef30996
MM
428
429(define_function_unit "mult" 1 1
b8eb88d0
ILT
430 (and (eq_attr "type" "fmul")
431 (and (eq_attr "mode" "SF")
41f9efba 432 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
c8e18a2b 433 7 0)
8ef30996
MM
434
435(define_function_unit "mult" 1 1
b8eb88d0 436 (and (eq_attr "type" "fmul")
e9a25f70 437 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
c8e18a2b 438 4 0)
8ef30996
MM
439
440(define_function_unit "mult" 1 1
b8eb88d0
ILT
441 (and (eq_attr "type" "fmul")
442 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
c8e18a2b 443 5 0)
8ef30996 444
bb621ad7 445(define_function_unit "mult" 1 1
b8eb88d0
ILT
446 (and (eq_attr "type" "fmul")
447 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
448 8 0)
449
8ef30996 450(define_function_unit "mult" 1 1
b8eb88d0 451 (and (eq_attr "type" "fmul")
41f9efba 452 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
c8e18a2b 453 8 0)
8ef30996
MM
454
455(define_function_unit "mult" 1 1
b8eb88d0 456 (and (eq_attr "type" "fmul")
e9a25f70 457 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
c8e18a2b 458 5 0)
8ef30996
MM
459
460(define_function_unit "mult" 1 1
b8eb88d0
ILT
461 (and (eq_attr "type" "fmul")
462 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
c8e18a2b 463 6 0)
8ef30996
MM
464
465(define_function_unit "divide" 1 1
b8eb88d0
ILT
466 (and (eq_attr "type" "fdiv")
467 (and (eq_attr "mode" "SF")
41f9efba 468 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
c8e18a2b 469 23 0)
8ef30996
MM
470
471(define_function_unit "divide" 1 1
b8eb88d0 472 (and (eq_attr "type" "fdiv")
e9a25f70 473 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
c8e18a2b 474 12 0)
8ef30996
MM
475
476(define_function_unit "divide" 1 1
b8eb88d0
ILT
477 (and (eq_attr "type" "fdiv")
478 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
c8e18a2b 479 15 0)
8ef30996
MM
480
481(define_function_unit "divide" 1 1
b8eb88d0
ILT
482 (and (eq_attr "type" "fdiv")
483 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
484 32 0)
485
486(define_function_unit "divide" 1 1
b8eb88d0
ILT
487 (and (eq_attr "type" "fdiv")
488 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
489 21 0)
490
491(define_function_unit "divide" 1 1
492 (and (eq_attr "type" "fdiv")
493 (and (eq_attr "mode" "DF")
41f9efba 494 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
c8e18a2b 495 36 0)
8ef30996
MM
496
497(define_function_unit "divide" 1 1
b8eb88d0 498 (and (eq_attr "type" "fdiv")
e9a25f70 499 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
c8e18a2b 500 19 0)
8ef30996
MM
501
502(define_function_unit "divide" 1 1
b8eb88d0
ILT
503 (and (eq_attr "type" "fdiv")
504 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
c8e18a2b 505 16 0)
8ef30996 506
bb621ad7 507(define_function_unit "divide" 1 1
b8eb88d0
ILT
508 (and (eq_attr "type" "fdiv")
509 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
510 61 0)
511
512;;; ??? Is this number right?
513(define_function_unit "divide" 1 1
5ce6f47b 514 (and (eq_attr "type" "fsqrt,frsqrt")
41f9efba 515 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
bb621ad7 516 54 0)
b8eb88d0 517
bb621ad7 518(define_function_unit "divide" 1 1
5ce6f47b 519 (and (eq_attr "type" "fsqrt,frsqrt")
b8eb88d0 520 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
521 31 0)
522
b8eb88d0 523(define_function_unit "divide" 1 1
5ce6f47b 524 (and (eq_attr "type" "fsqrt,frsqrt")
b8eb88d0
ILT
525 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
526 21 0)
527
bb621ad7
JW
528;;; ??? Is this number right?
529(define_function_unit "divide" 1 1
5ce6f47b 530 (and (eq_attr "type" "fsqrt,frsqrt")
41f9efba 531 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
bb621ad7 532 112 0)
b8eb88d0 533
bb621ad7 534(define_function_unit "divide" 1 1
5ce6f47b 535 (and (eq_attr "type" "fsqrt,frsqrt")
b8eb88d0 536 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7 537 60 0)
8ef30996 538
b8eb88d0 539(define_function_unit "divide" 1 1
5ce6f47b 540 (and (eq_attr "type" "fsqrt,frsqrt")
b8eb88d0
ILT
541 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
542 36 0)
543
8fbaea49
JW
544;; R4300 FP instruction classes treated as part of the "imuldiv"
545;; functional unit:
546
547(define_function_unit "imuldiv" 1 0
41f9efba 548 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
8fbaea49
JW
549 3 3)
550
aa4e54c4 551(define_function_unit "imuldiv" 1 0
41f9efba 552 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
aa4e54c4
JW
553 1 1)
554
8fbaea49 555(define_function_unit "imuldiv" 1 0
41f9efba 556 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
8fbaea49
JW
557 5 5)
558(define_function_unit "imuldiv" 1 0
41f9efba 559 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
8fbaea49
JW
560 8 8)
561
562(define_function_unit "imuldiv" 1 0
5ce6f47b 563 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
41f9efba 564 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
8fbaea49
JW
565 29 29)
566(define_function_unit "imuldiv" 1 0
5ce6f47b 567 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
41f9efba 568 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
8fbaea49 569 58 58)
ddd8ab48
MM
570\f
571;; The following functional units do not use the cpu type, and use
572;; much less memory in genattrtab.c.
573
c8e18a2b
TW
574;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
575;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
7a38df19 576;;
c8e18a2b 577;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
7a38df19 578;;
c8e18a2b
TW
579;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
580;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
7a38df19 581;;
c8e18a2b
TW
582;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
583;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
7a38df19 584;;
c8e18a2b
TW
585;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
586;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
7a38df19 587;;
c8e18a2b
TW
588;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
589;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
7a38df19 590;;
c8e18a2b
TW
591;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
592;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
7a38df19 593;;
c8e18a2b
TW
594;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
595;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
a0b6cdee 596\f
5ce6f47b
EC
597;; Include scheduling descriptions.
598
599(include "5400.md")
600(include "5500.md")
601(include "sr71k.md")
602
603
a0b6cdee
GM
604;;
605;; ....................
606;;
607;; CONDITIONAL TRAPS
608;;
609;; ....................
610;;
ddd8ab48 611
a0b6cdee
GM
612(define_insn "trap"
613 [(trap_if (const_int 1) (const_int 0))]
614 ""
615 "*
616{
617 if (ISA_HAS_COND_TRAP)
618 return \"teq\\t$0,$0\";
4dffef52
AO
619 else if (TARGET_MIPS16)
620 return \"break 0\";
a0b6cdee
GM
621 else
622 return \"break\";
623}")
624
625(define_expand "conditional_trap"
626 [(trap_if (match_operator 0 "cmp_op"
627 [(match_dup 2) (match_dup 3)])
628 (match_operand 1 "const_int_operand" ""))]
629 "ISA_HAS_COND_TRAP"
630 "
631{
632 mips_gen_conditional_trap (operands);
633 DONE;
634}")
635
636;; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a
637;; 2nd arg of any CONST_INT, so this insn must appear first.
638;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
639
640(define_insn ""
641 [(trap_if (match_operator 0 "trap_cmp_op"
642 [(match_operand:SI 1 "reg_or_0_operand" "d")
643 (match_operand:SI 2 "nonmemory_operand" "dI")])
644 (const_int 0))]
645 "ISA_HAS_COND_TRAP"
646 "t%C0\\t%z1,%z2")
8ef30996
MM
647\f
648;;
649;; ....................
650;;
651;; ADDITION
652;;
653;; ....................
654;;
655
656(define_insn "adddf3"
657 [(set (match_operand:DF 0 "register_operand" "=f")
658 (plus:DF (match_operand:DF 1 "register_operand" "f")
659 (match_operand:DF 2 "register_operand" "f")))]
46299de9 660 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
661 "add.d\\t%0,%1,%2"
662 [(set_attr "type" "fadd")
0ff83799 663 (set_attr "mode" "DF")])
8ef30996
MM
664
665(define_insn "addsf3"
666 [(set (match_operand:SF 0 "register_operand" "=f")
667 (plus:SF (match_operand:SF 1 "register_operand" "f")
668 (match_operand:SF 2 "register_operand" "f")))]
669 "TARGET_HARD_FLOAT"
670 "add.s\\t%0,%1,%2"
671 [(set_attr "type" "fadd")
0ff83799 672 (set_attr "mode" "SF")])
8ef30996 673
71cd5224 674(define_expand "addsi3"
cafe096b
EC
675 [(set (match_operand:SI 0 "register_operand" "")
676 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
677 (match_operand:SI 2 "arith_operand" "")))]
8ef30996 678 ""
71cd5224
RS
679 "
680{
2bcb2ab3
GK
681 /* The mips16 assembler handles -32768 correctly, and so does gas,
682 but some other MIPS assemblers think that -32768 needs to be
683 loaded into a register before it can be added in. */
684 if (! TARGET_MIPS16
685 && ! TARGET_GAS
686 && GET_CODE (operands[2]) == CONST_INT
687 && INTVAL (operands[2]) == -32768)
71cd5224 688 operands[2] = force_reg (SImode, operands[2]);
4f5bd6d7
AO
689
690 /* If a large stack adjustment was forced into a register, we may be
691 asked to generate rtx such as:
692
693 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
694
695 but no such instruction is available in mips16. Handle it by
696 using a temporary. */
697 if (TARGET_MIPS16
698 && REGNO (operands[0]) == STACK_POINTER_REGNUM
699 && ((GET_CODE (operands[1]) == REG
700 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
701 || GET_CODE (operands[2]) != CONST_INT))
702 {
703 rtx tmp = gen_reg_rtx (SImode);
704
705 emit_move_insn (tmp, operands[1]);
706 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
707 emit_move_insn (operands[0], tmp);
708 DONE;
709 }
71cd5224
RS
710}")
711
712(define_insn "addsi3_internal"
cafe096b
EC
713 [(set (match_operand:SI 0 "register_operand" "=d,d")
714 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
715 (match_operand:SI 2 "arith_operand" "d,Q")))]
2bcb2ab3
GK
716 "! TARGET_MIPS16
717 && (TARGET_GAS
718 || GET_CODE (operands[2]) != CONST_INT
719 || INTVAL (operands[2]) != -32768)"
cafe096b
EC
720 "@
721 addu\\t%0,%z1,%2
722 addiu\\t%0,%z1,%2"
8ef30996 723 [(set_attr "type" "arith")
0ff83799 724 (set_attr "mode" "SI")])
8ef30996 725
2bcb2ab3
GK
726;; For the mips16, we need to recognize stack pointer additions
727;; explicitly, since we don't have a constraint for $sp. These insns
728;; will be generated by the save_restore_insns functions.
729
730(define_insn ""
731 [(set (reg:SI 29)
732 (plus:SI (reg:SI 29)
733 (match_operand:SI 0 "small_int" "I")))]
734 "TARGET_MIPS16"
735 "addu\\t%$,%$,%0"
736 [(set_attr "type" "arith")
737 (set_attr "mode" "SI")
738 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
0ff83799
MM
739 (const_int 4)
740 (const_int 8)))])
2bcb2ab3
GK
741
742(define_insn ""
743 [(set (match_operand:SI 0 "register_operand" "=d")
744 (plus:SI (reg:SI 29)
745 (match_operand:SI 1 "small_int" "I")))]
746 "TARGET_MIPS16"
747 "addu\\t%0,%$,%1"
748 [(set_attr "type" "arith")
749 (set_attr "mode" "SI")
750 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
0ff83799
MM
751 (const_int 4)
752 (const_int 8)))])
2bcb2ab3
GK
753
754(define_insn ""
755 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
756 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
cafe096b 757 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
2bcb2ab3
GK
758 "TARGET_MIPS16
759 && (GET_CODE (operands[1]) != REG
760 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
761 || M16_REG_P (REGNO (operands[1]))
762 || REGNO (operands[1]) == ARG_POINTER_REGNUM
763 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
764 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
765 && (GET_CODE (operands[2]) != REG
766 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
767 || M16_REG_P (REGNO (operands[2]))
768 || REGNO (operands[2]) == ARG_POINTER_REGNUM
769 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
770 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
771 "*
772{
773 if (REGNO (operands[0]) == REGNO (operands[1]))
774 return \"addu\\t%0,%2\";
775 return \"addu\\t%0,%1,%2\";
776}"
777 [(set_attr "type" "arith")
778 (set_attr "mode" "SI")
779 (set_attr_alternative "length"
780 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
0ff83799
MM
781 (const_int 4)
782 (const_int 8))
2bcb2ab3 783 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
0ff83799
MM
784 (const_int 4)
785 (const_int 8))
786 (const_int 4)])])
2bcb2ab3
GK
787
788
789;; On the mips16, we can sometimes split an add of a constant which is
790;; a 4 byte instruction into two adds which are both 2 byte
791;; instructions. There are two cases: one where we are adding a
792;; constant plus a register to another register, and one where we are
793;; simply adding a constant to a register.
794
795(define_split
796 [(set (match_operand:SI 0 "register_operand" "")
797 (plus:SI (match_dup 0)
798 (match_operand:SI 1 "const_int_operand" "")))]
2ca2d9ee 799 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
800 && GET_CODE (operands[0]) == REG
801 && M16_REG_P (REGNO (operands[0]))
802 && GET_CODE (operands[1]) == CONST_INT
803 && ((INTVAL (operands[1]) > 0x7f
804 && INTVAL (operands[1]) <= 0x7f + 0x7f)
805 || (INTVAL (operands[1]) < - 0x80
806 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
807 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
808 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
809 "
810{
811 HOST_WIDE_INT val = INTVAL (operands[1]);
812
813 if (val >= 0)
814 {
815 operands[1] = GEN_INT (0x7f);
816 operands[2] = GEN_INT (val - 0x7f);
817 }
818 else
819 {
820 operands[1] = GEN_INT (- 0x80);
821 operands[2] = GEN_INT (val + 0x80);
822 }
823}")
824
825(define_split
826 [(set (match_operand:SI 0 "register_operand" "")
827 (plus:SI (match_operand:SI 1 "register_operand" "")
828 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 829 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
830 && GET_CODE (operands[0]) == REG
831 && M16_REG_P (REGNO (operands[0]))
832 && GET_CODE (operands[1]) == REG
833 && M16_REG_P (REGNO (operands[1]))
834 && REGNO (operands[0]) != REGNO (operands[1])
835 && GET_CODE (operands[2]) == CONST_INT
836 && ((INTVAL (operands[2]) > 0x7
837 && INTVAL (operands[2]) <= 0x7 + 0x7f)
838 || (INTVAL (operands[2]) < - 0x8
839 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
840 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
841 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
842 "
843{
844 HOST_WIDE_INT val = INTVAL (operands[2]);
845
846 if (val >= 0)
847 {
848 operands[2] = GEN_INT (0x7);
849 operands[3] = GEN_INT (val - 0x7);
850 }
851 else
852 {
853 operands[2] = GEN_INT (- 0x8);
854 operands[3] = GEN_INT (val + 0x8);
855 }
856}")
857
8ef30996
MM
858(define_expand "adddi3"
859 [(parallel [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
860 (plus:DI (match_operand:DI 1 "register_operand" "")
861 (match_operand:DI 2 "arith_operand" "")))
8ef30996 862 (clobber (match_dup 3))])]
2bcb2ab3 863 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
92b4cee1
MM
864 "
865{
2bcb2ab3
GK
866 /* The mips16 assembler handles -32768 correctly, and so does gas,
867 but some other MIPS assemblers think that -32768 needs to be
868 loaded into a register before it can be added in. */
869 if (! TARGET_MIPS16
870 && ! TARGET_GAS
871 && GET_CODE (operands[2]) == CONST_INT
872 && INTVAL (operands[2]) == -32768)
b0565769 873 operands[2] = force_reg (DImode, operands[2]);
92b4cee1 874
4f5bd6d7
AO
875 /* If a large stack adjustment was forced into a register, we may be
876 asked to generate rtx such as:
877
878 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
879
880 but no such instruction is available in mips16. Handle it by
881 using a temporary. */
882 if (TARGET_MIPS16
883 && REGNO (operands[0]) == STACK_POINTER_REGNUM
884 && ((GET_CODE (operands[1]) == REG
885 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
886 || GET_CODE (operands[2]) != CONST_INT))
887 {
888 rtx tmp = gen_reg_rtx (DImode);
889
890 emit_move_insn (tmp, operands[1]);
891 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
892 emit_move_insn (operands[0], tmp);
893 DONE;
894 }
895
bb621ad7
JW
896 if (TARGET_64BIT)
897 {
898 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
899 operands[2]));
900 DONE;
901 }
902
92b4cee1
MM
903 operands[3] = gen_reg_rtx (SImode);
904}")
8ef30996
MM
905
906(define_insn "adddi3_internal_1"
907 [(set (match_operand:DI 0 "register_operand" "=d,&d")
908 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
909 (match_operand:DI 2 "register_operand" "d,d")))
910 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
2bcb2ab3 911 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
912 "*
913{
914 return (REGNO (operands[0]) == REGNO (operands[1])
915 && REGNO (operands[0]) == REGNO (operands[2]))
916 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
917 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
918}"
92b4cee1
MM
919 [(set_attr "type" "darith")
920 (set_attr "mode" "DI")
0ff83799 921 (set_attr "length" "16")])
8ef30996
MM
922
923(define_split
924 [(set (match_operand:DI 0 "register_operand" "")
925 (plus:DI (match_operand:DI 1 "register_operand" "")
926 (match_operand:DI 2 "register_operand" "")))
927 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
928 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
929 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
930 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
931 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
932 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
933 && (REGNO (operands[0]) != REGNO (operands[1])
934 || REGNO (operands[0]) != REGNO (operands[2]))"
935
936 [(set (subreg:SI (match_dup 0) 0)
937 (plus:SI (subreg:SI (match_dup 1) 0)
938 (subreg:SI (match_dup 2) 0)))
939
940 (set (match_dup 3)
34b650b3 941 (ltu:SI (subreg:SI (match_dup 0) 0)
8ef30996
MM
942 (subreg:SI (match_dup 2) 0)))
943
ddef6bc7
JJ
944 (set (subreg:SI (match_dup 0) 4)
945 (plus:SI (subreg:SI (match_dup 1) 4)
946 (subreg:SI (match_dup 2) 4)))
8ef30996 947
ddef6bc7
JJ
948 (set (subreg:SI (match_dup 0) 4)
949 (plus:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
950 (match_dup 3)))]
951 "")
952
953(define_split
954 [(set (match_operand:DI 0 "register_operand" "")
955 (plus:DI (match_operand:DI 1 "register_operand" "")
956 (match_operand:DI 2 "register_operand" "")))
957 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
958 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
959 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
960 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
961 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
962 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
963 && (REGNO (operands[0]) != REGNO (operands[1])
964 || REGNO (operands[0]) != REGNO (operands[2]))"
965
ddef6bc7
JJ
966 [(set (subreg:SI (match_dup 0) 4)
967 (plus:SI (subreg:SI (match_dup 1) 4)
968 (subreg:SI (match_dup 2) 4)))
8ef30996
MM
969
970 (set (match_dup 3)
ddef6bc7
JJ
971 (ltu:SI (subreg:SI (match_dup 0) 4)
972 (subreg:SI (match_dup 2) 4)))
8ef30996
MM
973
974 (set (subreg:SI (match_dup 0) 0)
975 (plus:SI (subreg:SI (match_dup 1) 0)
976 (subreg:SI (match_dup 2) 0)))
977
978 (set (subreg:SI (match_dup 0) 0)
979 (plus:SI (subreg:SI (match_dup 0) 0)
980 (match_dup 3)))]
981 "")
982
983(define_insn "adddi3_internal_2"
984 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
985 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
986 (match_operand:DI 2 "small_int" "P,J,N")))
987 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
2bcb2ab3 988 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
82301b88
JL
989 && (TARGET_GAS
990 || GET_CODE (operands[2]) != CONST_INT
991 || INTVAL (operands[2]) != -32768)"
8ef30996
MM
992 "@
993 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
994 move\\t%L0,%L1\;move\\t%M0,%M1
995 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
92b4cee1
MM
996 [(set_attr "type" "darith")
997 (set_attr "mode" "DI")
0ff83799 998 (set_attr "length" "12,8,16")])
8ef30996
MM
999
1000(define_split
1001 [(set (match_operand:DI 0 "register_operand" "")
1002 (plus:DI (match_operand:DI 1 "register_operand" "")
1003 (match_operand:DI 2 "small_int" "")))
13c508d9 1004 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1005 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1006 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1007 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1008 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1009 && INTVAL (operands[2]) > 0"
1010
1011 [(set (subreg:SI (match_dup 0) 0)
1012 (plus:SI (subreg:SI (match_dup 1) 0)
1013 (match_dup 2)))
1014
1015 (set (match_dup 3)
34b650b3 1016 (ltu:SI (subreg:SI (match_dup 0) 0)
8ef30996
MM
1017 (match_dup 2)))
1018
ddef6bc7
JJ
1019 (set (subreg:SI (match_dup 0) 4)
1020 (plus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1021 (match_dup 3)))]
1022 "")
1023
1024(define_split
1025 [(set (match_operand:DI 0 "register_operand" "")
1026 (plus:DI (match_operand:DI 1 "register_operand" "")
1027 (match_operand:DI 2 "small_int" "")))
13c508d9 1028 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1029 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1030 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1031 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1032 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1033 && INTVAL (operands[2]) > 0"
1034
ddef6bc7
JJ
1035 [(set (subreg:SI (match_dup 0) 4)
1036 (plus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1037 (match_dup 2)))
1038
1039 (set (match_dup 3)
ddef6bc7 1040 (ltu:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
1041 (match_dup 2)))
1042
1043 (set (subreg:SI (match_dup 0) 0)
1044 (plus:SI (subreg:SI (match_dup 1) 0)
1045 (match_dup 3)))]
1046 "")
bb621ad7
JW
1047
1048(define_insn "adddi3_internal_3"
cafe096b
EC
1049 [(set (match_operand:DI 0 "register_operand" "=d,d")
1050 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
1051 (match_operand:DI 2 "arith_operand" "d,Q")))]
2bcb2ab3
GK
1052 "TARGET_64BIT
1053 && !TARGET_MIPS16
1054 && (TARGET_GAS
1055 || GET_CODE (operands[2]) != CONST_INT
1056 || INTVAL (operands[2]) != -32768)"
cafe096b
EC
1057 "@
1058 daddu\\t%0,%z1,%2
1059 daddiu\\t%0,%z1,%2"
bb621ad7 1060 [(set_attr "type" "darith")
0ff83799 1061 (set_attr "mode" "DI")])
bb621ad7 1062
2bcb2ab3
GK
1063;; For the mips16, we need to recognize stack pointer additions
1064;; explicitly, since we don't have a constraint for $sp. These insns
1065;; will be generated by the save_restore_insns functions.
1066
1067(define_insn ""
1068 [(set (reg:DI 29)
1069 (plus:DI (reg:DI 29)
1070 (match_operand:DI 0 "small_int" "I")))]
1071 "TARGET_MIPS16 && TARGET_64BIT"
1072 "daddu\\t%$,%$,%0"
1073 [(set_attr "type" "arith")
1074 (set_attr "mode" "DI")
1075 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
0ff83799
MM
1076 (const_int 4)
1077 (const_int 8)))])
2bcb2ab3
GK
1078
1079(define_insn ""
1080 [(set (match_operand:DI 0 "register_operand" "=d")
1081 (plus:DI (reg:DI 29)
1082 (match_operand:DI 1 "small_int" "I")))]
1083 "TARGET_MIPS16 && TARGET_64BIT"
1084 "daddu\\t%0,%$,%1"
1085 [(set_attr "type" "arith")
1086 (set_attr "mode" "DI")
1087 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
0ff83799
MM
1088 (const_int 4)
1089 (const_int 8)))])
2bcb2ab3
GK
1090
1091(define_insn ""
1092 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1093 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
cafe096b 1094 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
2bcb2ab3
GK
1095 "TARGET_MIPS16 && TARGET_64BIT
1096 && (GET_CODE (operands[1]) != REG
1097 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1098 || M16_REG_P (REGNO (operands[1]))
1099 || REGNO (operands[1]) == ARG_POINTER_REGNUM
1100 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1101 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1102 && (GET_CODE (operands[2]) != REG
1103 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1104 || M16_REG_P (REGNO (operands[2]))
1105 || REGNO (operands[2]) == ARG_POINTER_REGNUM
1106 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1107 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1108 "*
1109{
1110 if (REGNO (operands[0]) == REGNO (operands[1]))
1111 return \"daddu\\t%0,%2\";
1112 return \"daddu\\t%0,%1,%2\";
1113}"
1114 [(set_attr "type" "arith")
1115 (set_attr "mode" "DI")
1116 (set_attr_alternative "length"
1117 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
0ff83799
MM
1118 (const_int 4)
1119 (const_int 8))
2bcb2ab3 1120 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
0ff83799
MM
1121 (const_int 4)
1122 (const_int 8))
1123 (const_int 4)])])
2bcb2ab3
GK
1124
1125
1126;; On the mips16, we can sometimes split an add of a constant which is
1127;; a 4 byte instruction into two adds which are both 2 byte
1128;; instructions. There are two cases: one where we are adding a
1129;; constant plus a register to another register, and one where we are
1130;; simply adding a constant to a register.
1131
1132(define_split
1133 [(set (match_operand:DI 0 "register_operand" "")
1134 (plus:DI (match_dup 0)
1135 (match_operand:DI 1 "const_int_operand" "")))]
2ca2d9ee 1136 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
1137 && GET_CODE (operands[0]) == REG
1138 && M16_REG_P (REGNO (operands[0]))
1139 && GET_CODE (operands[1]) == CONST_INT
1140 && ((INTVAL (operands[1]) > 0xf
1141 && INTVAL (operands[1]) <= 0xf + 0xf)
1142 || (INTVAL (operands[1]) < - 0x10
1143 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1144 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1145 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1146 "
1147{
1148 HOST_WIDE_INT val = INTVAL (operands[1]);
1149
1150 if (val >= 0)
1151 {
1152 operands[1] = GEN_INT (0xf);
1153 operands[2] = GEN_INT (val - 0xf);
1154 }
1155 else
1156 {
1157 operands[1] = GEN_INT (- 0x10);
1158 operands[2] = GEN_INT (val + 0x10);
1159 }
1160}")
1161
1162(define_split
1163 [(set (match_operand:DI 0 "register_operand" "")
1164 (plus:DI (match_operand:DI 1 "register_operand" "")
1165 (match_operand:DI 2 "const_int_operand" "")))]
2ca2d9ee 1166 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
1167 && GET_CODE (operands[0]) == REG
1168 && M16_REG_P (REGNO (operands[0]))
1169 && GET_CODE (operands[1]) == REG
1170 && M16_REG_P (REGNO (operands[1]))
1171 && REGNO (operands[0]) != REGNO (operands[1])
1172 && GET_CODE (operands[2]) == CONST_INT
1173 && ((INTVAL (operands[2]) > 0x7
1174 && INTVAL (operands[2]) <= 0x7 + 0xf)
1175 || (INTVAL (operands[2]) < - 0x8
1176 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1177 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1178 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1179 "
1180{
1181 HOST_WIDE_INT val = INTVAL (operands[2]);
1182
1183 if (val >= 0)
1184 {
1185 operands[2] = GEN_INT (0x7);
1186 operands[3] = GEN_INT (val - 0x7);
1187 }
1188 else
1189 {
1190 operands[2] = GEN_INT (- 0x8);
1191 operands[3] = GEN_INT (val + 0x8);
1192 }
1193}")
bb621ad7
JW
1194
1195(define_insn "addsi3_internal_2"
cafe096b
EC
1196 [(set (match_operand:DI 0 "register_operand" "=d,d")
1197 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
1198 (match_operand:SI 2 "arith_operand" "d,Q"))))]
2bcb2ab3
GK
1199 "TARGET_64BIT
1200 && !TARGET_MIPS16
1201 && (TARGET_GAS
1202 || GET_CODE (operands[2]) != CONST_INT
1203 || INTVAL (operands[2]) != -32768)"
cafe096b
EC
1204 "@
1205 addu\\t%0,%z1,%2
1206 addiu\\t%0,%z1,%2"
bb621ad7 1207 [(set_attr "type" "arith")
0ff83799 1208 (set_attr "mode" "SI")])
bb621ad7 1209
2bcb2ab3
GK
1210(define_insn ""
1211 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1212 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
cafe096b 1213 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
2bcb2ab3
GK
1214 "TARGET_MIPS16 && TARGET_64BIT"
1215 "*
1216{
1217 if (REGNO (operands[0]) == REGNO (operands[1]))
1218 return \"addu\\t%0,%2\";
1219 return \"addu\\t%0,%1,%2\";
1220}"
1221 [(set_attr "type" "arith")
1222 (set_attr "mode" "SI")
1223 (set_attr_alternative "length"
1224 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
0ff83799
MM
1225 (const_int 4)
1226 (const_int 8))
2bcb2ab3 1227 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
0ff83799
MM
1228 (const_int 4)
1229 (const_int 8))
1230 (const_int 4)])])
2bcb2ab3 1231
8ef30996
MM
1232\f
1233;;
1234;; ....................
1235;;
1236;; SUBTRACTION
1237;;
1238;; ....................
1239;;
1240
1241(define_insn "subdf3"
1242 [(set (match_operand:DF 0 "register_operand" "=f")
1243 (minus:DF (match_operand:DF 1 "register_operand" "f")
1244 (match_operand:DF 2 "register_operand" "f")))]
46299de9 1245 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
1246 "sub.d\\t%0,%1,%2"
1247 [(set_attr "type" "fadd")
0ff83799 1248 (set_attr "mode" "DF")])
8ef30996
MM
1249
1250(define_insn "subsf3"
1251 [(set (match_operand:SF 0 "register_operand" "=f")
1252 (minus:SF (match_operand:SF 1 "register_operand" "f")
1253 (match_operand:SF 2 "register_operand" "f")))]
1254 "TARGET_HARD_FLOAT"
1255 "sub.s\\t%0,%1,%2"
1256 [(set_attr "type" "fadd")
0ff83799 1257 (set_attr "mode" "SF")])
8ef30996 1258
71cd5224 1259(define_expand "subsi3"
8ef30996
MM
1260 [(set (match_operand:SI 0 "register_operand" "=d")
1261 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1262 (match_operand:SI 2 "arith_operand" "dI")))]
1263 ""
71cd5224
RS
1264 "
1265{
2bcb2ab3
GK
1266 if (GET_CODE (operands[2]) == CONST_INT
1267 && (INTVAL (operands[2]) == -32768
1268 || (TARGET_MIPS16
1269 && INTVAL (operands[2]) == -0x4000)))
71cd5224
RS
1270 operands[2] = force_reg (SImode, operands[2]);
1271}")
1272
1273(define_insn "subsi3_internal"
1274 [(set (match_operand:SI 0 "register_operand" "=d")
1275 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1276 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3
GK
1277 "!TARGET_MIPS16
1278 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
9b190d1c 1279 "subu\\t%0,%z1,%2"
8ef30996 1280 [(set_attr "type" "arith")
0ff83799 1281 (set_attr "mode" "SI")])
8ef30996 1282
2bcb2ab3
GK
1283;; For the mips16, we need to recognize stack pointer subtractions
1284;; explicitly, since we don't have a constraint for $sp. These insns
1285;; will be generated by the save_restore_insns functions.
1286
1287(define_insn ""
1288 [(set (reg:SI 29)
1289 (minus:SI (reg:SI 29)
1290 (match_operand:SI 0 "small_int" "I")))]
1291 "TARGET_MIPS16
1292 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1293 "addu\\t%$,%$,%n0"
1294 [(set_attr "type" "arith")
1295 (set_attr "mode" "SI")
1296 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
0ff83799
MM
1297 (const_int 4)
1298 (const_int 8)))])
2bcb2ab3
GK
1299
1300(define_insn ""
1301 [(set (match_operand:SI 0 "register_operand" "=d")
1302 (minus:SI (reg:SI 29)
1303 (match_operand:SI 1 "small_int" "I")))]
1304 "TARGET_MIPS16
1305 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1306 "addu\\t%0,%$,%n1"
1307 [(set_attr "type" "arith")
1308 (set_attr "mode" "SI")
1309 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
0ff83799
MM
1310 (const_int 4)
1311 (const_int 8)))])
2bcb2ab3
GK
1312
1313
1314(define_insn ""
1315 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1316 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1317 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1318 "TARGET_MIPS16
1319 && (GET_CODE (operands[2]) != CONST_INT
1320 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1321 "*
1322{
1323 if (REGNO (operands[0]) == REGNO (operands[1]))
1324 return \"subu\\t%0,%2\";
1325 return \"subu\\t%0,%1,%2\";
1326}"
1327 [(set_attr "type" "arith")
1328 (set_attr "mode" "SI")
1329 (set_attr_alternative "length"
1330 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
0ff83799
MM
1331 (const_int 4)
1332 (const_int 8))
2bcb2ab3 1333 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
0ff83799
MM
1334 (const_int 4)
1335 (const_int 8))
1336 (const_int 4)])])
2bcb2ab3 1337
5bdc5878 1338;; On the mips16, we can sometimes split a subtract of a constant
2bcb2ab3
GK
1339;; which is a 4 byte instruction into two adds which are both 2 byte
1340;; instructions. There are two cases: one where we are setting a
1341;; register to a register minus a constant, and one where we are
1342;; simply subtracting a constant from a register.
1343
1344(define_split
1345 [(set (match_operand:SI 0 "register_operand" "")
1346 (minus:SI (match_dup 0)
1347 (match_operand:SI 1 "const_int_operand" "")))]
2ca2d9ee 1348 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
1349 && GET_CODE (operands[0]) == REG
1350 && M16_REG_P (REGNO (operands[0]))
1351 && GET_CODE (operands[1]) == CONST_INT
1352 && ((INTVAL (operands[1]) > 0x80
1353 && INTVAL (operands[1]) <= 0x80 + 0x80)
1354 || (INTVAL (operands[1]) < - 0x7f
1355 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1356 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1357 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1358 "
1359{
1360 HOST_WIDE_INT val = INTVAL (operands[1]);
1361
1362 if (val >= 0)
1363 {
1364 operands[1] = GEN_INT (0x80);
1365 operands[2] = GEN_INT (val - 0x80);
1366 }
1367 else
1368 {
1369 operands[1] = GEN_INT (- 0x7f);
1370 operands[2] = GEN_INT (val + 0x7f);
1371 }
1372}")
1373
1374(define_split
1375 [(set (match_operand:SI 0 "register_operand" "")
1376 (minus:SI (match_operand:SI 1 "register_operand" "")
1377 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 1378 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
1379 && GET_CODE (operands[0]) == REG
1380 && M16_REG_P (REGNO (operands[0]))
1381 && GET_CODE (operands[1]) == REG
1382 && M16_REG_P (REGNO (operands[1]))
1383 && REGNO (operands[0]) != REGNO (operands[1])
1384 && GET_CODE (operands[2]) == CONST_INT
1385 && ((INTVAL (operands[2]) > 0x8
1386 && INTVAL (operands[2]) <= 0x8 + 0x80)
1387 || (INTVAL (operands[2]) < - 0x7
1388 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1389 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1390 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1391 "
1392{
1393 HOST_WIDE_INT val = INTVAL (operands[2]);
1394
1395 if (val >= 0)
1396 {
1397 operands[2] = GEN_INT (0x8);
1398 operands[3] = GEN_INT (val - 0x8);
1399 }
1400 else
1401 {
1402 operands[2] = GEN_INT (- 0x7);
1403 operands[3] = GEN_INT (val + 0x7);
1404 }
1405}")
1406
8ef30996
MM
1407(define_expand "subdi3"
1408 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
1409 (minus:DI (match_operand:DI 1 "register_operand" "d")
1410 (match_operand:DI 2 "register_operand" "d")))
8ef30996 1411 (clobber (match_dup 3))])]
2bcb2ab3 1412 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
1413 "
1414{
1415 if (TARGET_64BIT)
1416 {
1417 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1418 operands[2]));
1419 DONE;
1420 }
1421
1422 operands[3] = gen_reg_rtx (SImode);
1423}")
8ef30996
MM
1424
1425(define_insn "subdi3_internal"
1426 [(set (match_operand:DI 0 "register_operand" "=d")
1427 (minus:DI (match_operand:DI 1 "register_operand" "d")
1428 (match_operand:DI 2 "register_operand" "d")))
1429 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 1430 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
1431 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1432 [(set_attr "type" "darith")
1433 (set_attr "mode" "DI")
0ff83799 1434 (set_attr "length" "16")])
8ef30996
MM
1435
1436(define_split
1437 [(set (match_operand:DI 0 "register_operand" "")
1438 (minus:DI (match_operand:DI 1 "register_operand" "")
1439 (match_operand:DI 2 "register_operand" "")))
1440 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1441 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1442 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1443 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1444 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1445 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1446
1447 [(set (match_dup 3)
34b650b3 1448 (ltu:SI (subreg:SI (match_dup 1) 0)
6d518002 1449 (subreg:SI (match_dup 2) 0)))
8ef30996
MM
1450
1451 (set (subreg:SI (match_dup 0) 0)
1452 (minus:SI (subreg:SI (match_dup 1) 0)
1453 (subreg:SI (match_dup 2) 0)))
1454
ddef6bc7
JJ
1455 (set (subreg:SI (match_dup 0) 4)
1456 (minus:SI (subreg:SI (match_dup 1) 4)
1457 (subreg:SI (match_dup 2) 4)))
8ef30996 1458
ddef6bc7
JJ
1459 (set (subreg:SI (match_dup 0) 4)
1460 (minus:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
1461 (match_dup 3)))]
1462 "")
1463
1464(define_split
1465 [(set (match_operand:DI 0 "register_operand" "")
1466 (minus:DI (match_operand:DI 1 "register_operand" "")
1467 (match_operand:DI 2 "register_operand" "")))
1468 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1469 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1470 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1471 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1472 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1473 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1474
1475 [(set (match_dup 3)
ddef6bc7
JJ
1476 (ltu:SI (subreg:SI (match_dup 1) 4)
1477 (subreg:SI (match_dup 2) 4)))
8ef30996 1478
ddef6bc7
JJ
1479 (set (subreg:SI (match_dup 0) 4)
1480 (minus:SI (subreg:SI (match_dup 1) 4)
1481 (subreg:SI (match_dup 2) 4)))
8ef30996
MM
1482
1483 (set (subreg:SI (match_dup 0) 0)
1484 (minus:SI (subreg:SI (match_dup 1) 0)
1485 (subreg:SI (match_dup 2) 0)))
1486
1487 (set (subreg:SI (match_dup 0) 0)
1488 (minus:SI (subreg:SI (match_dup 0) 0)
1489 (match_dup 3)))]
1490 "")
1491
1492(define_insn "subdi3_internal_2"
1493 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1494 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1495 (match_operand:DI 2 "small_int" "P,J,N")))
1496 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
2bcb2ab3
GK
1497 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1498 && INTVAL (operands[2]) != -32768"
8ef30996
MM
1499 "@
1500 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1501 move\\t%L0,%L1\;move\\t%M0,%M1
1502 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
92b4cee1
MM
1503 [(set_attr "type" "darith")
1504 (set_attr "mode" "DI")
0ff83799 1505 (set_attr "length" "12,8,16")])
8ef30996
MM
1506
1507(define_split
1508 [(set (match_operand:DI 0 "register_operand" "")
1509 (minus:DI (match_operand:DI 1 "register_operand" "")
1510 (match_operand:DI 2 "small_int" "")))
1511 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1512 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1513 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1514 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1515 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1516 && INTVAL (operands[2]) > 0"
1517
1518 [(set (match_dup 3)
34b650b3 1519 (ltu:SI (subreg:SI (match_dup 1) 0)
8ef30996
MM
1520 (match_dup 2)))
1521
1522 (set (subreg:SI (match_dup 0) 0)
1523 (minus:SI (subreg:SI (match_dup 1) 0)
1524 (match_dup 2)))
1525
ddef6bc7
JJ
1526 (set (subreg:SI (match_dup 0) 4)
1527 (minus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1528 (match_dup 3)))]
1529 "")
1530
1531(define_split
1532 [(set (match_operand:DI 0 "register_operand" "")
1533 (minus:DI (match_operand:DI 1 "register_operand" "")
1534 (match_operand:DI 2 "small_int" "")))
1535 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1536 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1537 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1538 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1539 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1540 && INTVAL (operands[2]) > 0"
1541
1542 [(set (match_dup 3)
ddef6bc7 1543 (ltu:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1544 (match_dup 2)))
1545
ddef6bc7
JJ
1546 (set (subreg:SI (match_dup 0) 4)
1547 (minus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1548 (match_dup 2)))
1549
1550 (set (subreg:SI (match_dup 0) 0)
1551 (minus:SI (subreg:SI (match_dup 1) 0)
1552 (match_dup 3)))]
1553 "")
1554
bb621ad7
JW
1555(define_insn "subdi3_internal_3"
1556 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
1557 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
1558 (match_operand:DI 2 "arith_operand" "dI")))]
2bcb2ab3
GK
1559 "TARGET_64BIT && !TARGET_MIPS16
1560 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
bb621ad7
JW
1561 "*
1562{
1563 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1564 ? \"daddu\\t%0,%z1,%n2\"
1565 : \"dsubu\\t%0,%z1,%2\";
1566}"
1567 [(set_attr "type" "darith")
0ff83799 1568 (set_attr "mode" "DI")])
bb621ad7 1569
2bcb2ab3
GK
1570;; For the mips16, we need to recognize stack pointer subtractions
1571;; explicitly, since we don't have a constraint for $sp. These insns
1572;; will be generated by the save_restore_insns functions.
1573
1574(define_insn ""
1575 [(set (reg:DI 29)
1576 (minus:DI (reg:DI 29)
1577 (match_operand:DI 0 "small_int" "I")))]
1578 "TARGET_MIPS16
1579 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1580 "daddu\\t%$,%$,%n0"
1581 [(set_attr "type" "arith")
1582 (set_attr "mode" "DI")
1583 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
0ff83799
MM
1584 (const_int 4)
1585 (const_int 8)))])
2bcb2ab3
GK
1586
1587(define_insn ""
1588 [(set (match_operand:DI 0 "register_operand" "=d")
1589 (minus:DI (reg:DI 29)
1590 (match_operand:DI 1 "small_int" "I")))]
1591 "TARGET_MIPS16
1592 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1593 "daddu\\t%0,%$,%n1"
1594 [(set_attr "type" "arith")
1595 (set_attr "mode" "DI")
1596 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
0ff83799
MM
1597 (const_int 4)
1598 (const_int 8)))])
2bcb2ab3
GK
1599
1600(define_insn ""
1601 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1602 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1603 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1604 "TARGET_MIPS16
1605 && (GET_CODE (operands[2]) != CONST_INT
1606 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1607 "*
1608{
1609 if (REGNO (operands[0]) == REGNO (operands[1]))
1610 return \"dsubu\\t%0,%2\";
1611 return \"dsubu\\t%0,%1,%2\";
1612}"
1613 [(set_attr "type" "arith")
1614 (set_attr "mode" "DI")
1615 (set_attr_alternative "length"
1616 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
0ff83799
MM
1617 (const_int 4)
1618 (const_int 8))
2bcb2ab3 1619 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
0ff83799
MM
1620 (const_int 4)
1621 (const_int 8))
1622 (const_int 4)])])
2bcb2ab3
GK
1623
1624;; On the mips16, we can sometimes split an add of a constant which is
1625;; a 4 byte instruction into two adds which are both 2 byte
1626;; instructions. There are two cases: one where we are adding a
1627;; constant plus a register to another register, and one where we are
1628;; simply adding a constant to a register.
1629
1630(define_split
1631 [(set (match_operand:DI 0 "register_operand" "")
1632 (minus:DI (match_dup 0)
1633 (match_operand:DI 1 "const_int_operand" "")))]
2ca2d9ee 1634 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
1635 && GET_CODE (operands[0]) == REG
1636 && M16_REG_P (REGNO (operands[0]))
1637 && GET_CODE (operands[1]) == CONST_INT
1638 && ((INTVAL (operands[1]) > 0x10
1639 && INTVAL (operands[1]) <= 0x10 + 0x10)
1640 || (INTVAL (operands[1]) < - 0xf
1641 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1642 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1643 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1644 "
1645{
1646 HOST_WIDE_INT val = INTVAL (operands[1]);
1647
1648 if (val >= 0)
1649 {
1650 operands[1] = GEN_INT (0xf);
1651 operands[2] = GEN_INT (val - 0xf);
1652 }
1653 else
1654 {
1655 operands[1] = GEN_INT (- 0x10);
1656 operands[2] = GEN_INT (val + 0x10);
1657 }
1658}")
1659
1660(define_split
1661 [(set (match_operand:DI 0 "register_operand" "")
1662 (minus:DI (match_operand:DI 1 "register_operand" "")
1663 (match_operand:DI 2 "const_int_operand" "")))]
2ca2d9ee 1664 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
1665 && GET_CODE (operands[0]) == REG
1666 && M16_REG_P (REGNO (operands[0]))
1667 && GET_CODE (operands[1]) == REG
1668 && M16_REG_P (REGNO (operands[1]))
1669 && REGNO (operands[0]) != REGNO (operands[1])
1670 && GET_CODE (operands[2]) == CONST_INT
1671 && ((INTVAL (operands[2]) > 0x8
1672 && INTVAL (operands[2]) <= 0x8 + 0x10)
1673 || (INTVAL (operands[2]) < - 0x7
1674 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1675 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1676 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1677 "
1678{
1679 HOST_WIDE_INT val = INTVAL (operands[2]);
1680
1681 if (val >= 0)
1682 {
1683 operands[2] = GEN_INT (0x8);
1684 operands[3] = GEN_INT (val - 0x8);
1685 }
1686 else
1687 {
1688 operands[2] = GEN_INT (- 0x7);
1689 operands[3] = GEN_INT (val + 0x7);
1690 }
1691}")
bb621ad7
JW
1692
1693(define_insn "subsi3_internal_2"
1694 [(set (match_operand:DI 0 "register_operand" "=d")
1695 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1696 (match_operand:SI 2 "arith_operand" "dI"))))]
2bcb2ab3
GK
1697 "TARGET_64BIT && !TARGET_MIPS16
1698 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
bb621ad7
JW
1699 "*
1700{
1701 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1702 ? \"addu\\t%0,%z1,%n2\"
1703 : \"subu\\t%0,%z1,%2\";
1704}"
1705 [(set_attr "type" "arith")
0ff83799 1706 (set_attr "mode" "DI")])
bb621ad7 1707
2bcb2ab3
GK
1708(define_insn ""
1709 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1710 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1711 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1712 "TARGET_64BIT && TARGET_MIPS16
1713 && (GET_CODE (operands[2]) != CONST_INT
1714 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1715 "*
1716{
1717 if (REGNO (operands[0]) == REGNO (operands[1]))
1718 return \"subu\\t%0,%2\";
1719 return \"subu\\t%0,%1,%2\";
1720}"
1721 [(set_attr "type" "arith")
1722 (set_attr "mode" "SI")
1723 (set_attr_alternative "length"
1724 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
0ff83799
MM
1725 (const_int 4)
1726 (const_int 8))
2bcb2ab3 1727 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
0ff83799
MM
1728 (const_int 4)
1729 (const_int 8))
1730 (const_int 4)])])
7a38df19 1731
2bcb2ab3 1732
8ef30996
MM
1733\f
1734;;
1735;; ....................
1736;;
1737;; MULTIPLICATION
1738;;
1739;; ....................
1740;;
1741
aa4e54c4
JW
1742;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1743;; operands may corrupt immediately following multiplies. This is a
1744;; simple fix to insert NOPs.
8fbaea49
JW
1745
1746(define_expand "muldf3"
8ef30996
MM
1747 [(set (match_operand:DF 0 "register_operand" "=f")
1748 (mult:DF (match_operand:DF 1 "register_operand" "f")
1749 (match_operand:DF 2 "register_operand" "f")))]
46299de9 1750 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8fbaea49
JW
1751 "
1752{
41f9efba 1753 if (!TARGET_MIPS4300)
8fbaea49
JW
1754 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1755 else
1756 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1757 DONE;
1758}")
1759
1760(define_insn "muldf3_internal"
1761 [(set (match_operand:DF 0 "register_operand" "=f")
1762 (mult:DF (match_operand:DF 1 "register_operand" "f")
1763 (match_operand:DF 2 "register_operand" "f")))]
41f9efba 1764 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_MIPS4300"
8ef30996
MM
1765 "mul.d\\t%0,%1,%2"
1766 [(set_attr "type" "fmul")
0ff83799 1767 (set_attr "mode" "DF")])
8ef30996 1768
8fbaea49
JW
1769(define_insn "muldf3_r4300"
1770 [(set (match_operand:DF 0 "register_operand" "=f")
1771 (mult:DF (match_operand:DF 1 "register_operand" "f")
1772 (match_operand:DF 2 "register_operand" "f")))]
41f9efba 1773 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_MIPS4300"
8fbaea49
JW
1774 "*
1775{
1776 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1777 if (TARGET_4300_MUL_FIX)
1778 output_asm_insn (\"nop\", operands);
1779 return \"\";
1780}"
1781 [(set_attr "type" "fmul")
1782 (set_attr "mode" "DF")
0ff83799 1783 (set_attr "length" "8")]) ;; mul.d + nop
8fbaea49
JW
1784
1785(define_expand "mulsf3"
8ef30996
MM
1786 [(set (match_operand:SF 0 "register_operand" "=f")
1787 (mult:SF (match_operand:SF 1 "register_operand" "f")
1788 (match_operand:SF 2 "register_operand" "f")))]
1789 "TARGET_HARD_FLOAT"
8fbaea49
JW
1790 "
1791{
41f9efba 1792 if (!TARGET_MIPS4300)
8fbaea49
JW
1793 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1794 else
1795 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1796 DONE;
1797}")
1798
1799(define_insn "mulsf3_internal"
1800 [(set (match_operand:SF 0 "register_operand" "=f")
1801 (mult:SF (match_operand:SF 1 "register_operand" "f")
1802 (match_operand:SF 2 "register_operand" "f")))]
41f9efba 1803 "TARGET_HARD_FLOAT && !TARGET_MIPS4300"
8ef30996
MM
1804 "mul.s\\t%0,%1,%2"
1805 [(set_attr "type" "fmul")
0ff83799 1806 (set_attr "mode" "SF")])
8ef30996 1807
8fbaea49
JW
1808(define_insn "mulsf3_r4300"
1809 [(set (match_operand:SF 0 "register_operand" "=f")
1810 (mult:SF (match_operand:SF 1 "register_operand" "f")
1811 (match_operand:SF 2 "register_operand" "f")))]
41f9efba 1812 "TARGET_HARD_FLOAT && TARGET_MIPS4300"
8fbaea49
JW
1813 "*
1814{
1815 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1816 if (TARGET_4300_MUL_FIX)
1817 output_asm_insn (\"nop\", operands);
1818 return \"\";
1819}"
1820 [(set_attr "type" "fmul")
1821 (set_attr "mode" "SF")
0ff83799 1822 (set_attr "length" "8")]) ;; mul.s + nop
8fbaea49 1823
cb923660 1824
46299de9
ILT
1825;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1826;; a multiply is in progress, it may give an incorrect result. Avoid
1827;; this by keeping the mflo with the mult on the R4000.
1828
1829(define_expand "mulsi3"
1830 [(set (match_operand:SI 0 "register_operand" "=l")
8ef30996
MM
1831 (mult:SI (match_operand:SI 1 "register_operand" "d")
1832 (match_operand:SI 2 "register_operand" "d")))
225b8835
ILT
1833 (clobber (match_scratch:SI 3 "=h"))
1834 (clobber (match_scratch:SI 4 "=a"))]
8ef30996 1835 ""
46299de9
ILT
1836 "
1837{
0e5a4ad8 1838 if (GENERATE_MULT3_SI || TARGET_MAD)
e9a25f70 1839 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
7dac2f89 1840 else if (!TARGET_MIPS4000 || TARGET_MIPS16)
46299de9
ILT
1841 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1842 else
1843 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1844 DONE;
1845}")
1846
e9a25f70 1847(define_insn "mulsi3_mult3"
e4f5c5d6 1848 [(set (match_operand:SI 0 "register_operand" "=d,l")
cb923660
KR
1849 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1850 (match_operand:SI 2 "register_operand" "d,d")))
1851 (clobber (match_scratch:SI 3 "=h,h"))
1852 (clobber (match_scratch:SI 4 "=l,X"))
1853 (clobber (match_scratch:SI 5 "=a,a"))]
0e5a4ad8 1854 "GENERATE_MULT3_SI
e4f5c5d6 1855 || TARGET_MAD"
cb923660
KR
1856 "*
1857{
1858 if (which_alternative == 1)
1859 return \"mult\\t%1,%2\";
0e5a4ad8 1860 if (TARGET_MAD
5ce6f47b
EC
1861 || TARGET_MIPS5400
1862 || TARGET_MIPS5500
ce3649d2 1863 || ISA_MIPS32
2d2a50c3 1864 || ISA_MIPS32R2
ce3649d2 1865 || ISA_MIPS64)
cb923660
KR
1866 return \"mul\\t%0,%1,%2\";
1867 return \"mult\\t%0,%1,%2\";
1868}"
e9a25f70 1869 [(set_attr "type" "imul")
0ff83799 1870 (set_attr "mode" "SI")])
e9a25f70 1871
cafe096b
EC
1872;; If a register gets allocated to LO, and we spill to memory, the reload
1873;; will include a move from LO to a GPR. Merge it into the multiplication
1874;; if it can set the GPR directly.
1875;;
1876;; Operand 0: LO
1877;; Operand 1: GPR (1st multiplication operand)
1878;; Operand 2: GPR (2nd multiplication operand)
1879;; Operand 3: HI
1880;; Operand 4: HILO
1881;; Operand 5: GPR (destination)
1882(define_peephole2
1883 [(parallel
1884 [(set (match_operand:SI 0 "register_operand" "")
1885 (mult:SI (match_operand:SI 1 "register_operand" "")
1886 (match_operand:SI 2 "register_operand" "")))
1887 (clobber (match_operand:SI 3 "register_operand" ""))
1888 (clobber (scratch:SI))
1889 (clobber (match_operand:SI 4 "register_operand" ""))])
1890 (set (match_operand:SI 5 "register_operand" "")
1891 (match_dup 0))]
1892 "GENERATE_MULT3_SI
1893 && true_regnum (operands[0]) == LO_REGNUM
1894 && GP_REG_P (true_regnum (operands[5]))
1895 && peep2_reg_dead_p (2, operands[0])"
1896 [(parallel
1897 [(set (match_dup 5)
1898 (mult:SI (match_dup 1)
1899 (match_dup 2)))
1900 (clobber (match_dup 3))
1901 (clobber (match_dup 0))
1902 (clobber (match_dup 4))])])
1903
46299de9
ILT
1904(define_insn "mulsi3_internal"
1905 [(set (match_operand:SI 0 "register_operand" "=l")
1906 (mult:SI (match_operand:SI 1 "register_operand" "d")
1907 (match_operand:SI 2 "register_operand" "d")))
225b8835
ILT
1908 (clobber (match_scratch:SI 3 "=h"))
1909 (clobber (match_scratch:SI 4 "=a"))]
7dac2f89 1910 "!TARGET_MIPS4000 || TARGET_MIPS16"
46299de9
ILT
1911 "mult\\t%1,%2"
1912 [(set_attr "type" "imul")
0ff83799 1913 (set_attr "mode" "SI")])
46299de9
ILT
1914
1915(define_insn "mulsi3_r4000"
1916 [(set (match_operand:SI 0 "register_operand" "=d")
1917 (mult:SI (match_operand:SI 1 "register_operand" "d")
1918 (match_operand:SI 2 "register_operand" "d")))
1919 (clobber (match_scratch:SI 3 "=h"))
225b8835
ILT
1920 (clobber (match_scratch:SI 4 "=l"))
1921 (clobber (match_scratch:SI 5 "=a"))]
7dac2f89 1922 "TARGET_MIPS4000 && !TARGET_MIPS16"
8ef30996
MM
1923 "*
1924{
1925 rtx xoperands[10];
1926
1927 xoperands[0] = operands[0];
c5c76735 1928 xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
8ef30996
MM
1929
1930 output_asm_insn (\"mult\\t%1,%2\", operands);
bb621ad7 1931 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
8ef30996
MM
1932 return \"\";
1933}"
1934 [(set_attr "type" "imul")
1935 (set_attr "mode" "SI")
0ff83799 1936 (set_attr "length" "12")]) ;; mult + mflo + delay
8ef30996 1937
e4f5c5d6
KR
1938;; Multiply-accumulate patterns
1939
1940;; For processors that can copy the output to a general register:
1941;;
cb923660
KR
1942;; The all-d alternative is needed because the combiner will find this
1943;; pattern and then register alloc/reload will move registers around to
1944;; make them fit, and we don't want to trigger unnecessary loads to LO.
e4f5c5d6
KR
1945;;
1946;; The last alternative should be made slightly less desirable, but adding
1947;; "?" to the constraint is too strong, and causes values to be loaded into
1948;; LO even when that's more costly. For now, using "*d" mostly does the
1949;; trick.
cb923660 1950(define_insn "*mul_acc_si"
e4f5c5d6 1951 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
cb923660
KR
1952 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1953 (match_operand:SI 2 "register_operand" "d,d,d"))
e4f5c5d6 1954 (match_operand:SI 3 "register_operand" "0,l,*d")))
cb923660
KR
1955 (clobber (match_scratch:SI 4 "=h,h,h"))
1956 (clobber (match_scratch:SI 5 "=X,3,l"))
1957 (clobber (match_scratch:SI 6 "=a,a,a"))
1958 (clobber (match_scratch:SI 7 "=X,X,d"))]
bbea0391
NC
1959 "(TARGET_MIPS3900
1960 || ISA_HAS_MADD_MSUB)
e4f5c5d6 1961 && !TARGET_MIPS16"
cb923660
KR
1962 "*
1963{
e2fe6aba 1964 static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
cb923660
KR
1965 if (which_alternative == 2)
1966 return \"#\";
0e5a4ad8
EC
1967 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1968 return \"#\";
cb923660
KR
1969 return madd[which_alternative];
1970}"
1d4047e0 1971 [(set_attr "type" "imadd,imadd,multi")
053665d7 1972 (set_attr "mode" "SI")
0ff83799 1973 (set_attr "length" "4,4,8")])
cb923660 1974
e4f5c5d6 1975;; Split the above insn if we failed to get LO allocated.
cb923660
KR
1976(define_split
1977 [(set (match_operand:SI 0 "register_operand" "")
1978 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1979 (match_operand:SI 2 "register_operand" ""))
1980 (match_operand:SI 3 "register_operand" "")))
1981 (clobber (match_scratch:SI 4 ""))
1982 (clobber (match_scratch:SI 5 ""))
1983 (clobber (match_scratch:SI 6 ""))
1984 (clobber (match_scratch:SI 7 ""))]
2ca2d9ee
EC
1985 "reload_completed && !TARGET_DEBUG_D_MODE
1986 && GP_REG_P (true_regnum (operands[0]))
1987 && GP_REG_P (true_regnum (operands[3]))"
cb923660
KR
1988 [(parallel [(set (match_dup 7)
1989 (mult:SI (match_dup 1) (match_dup 2)))
1990 (clobber (match_dup 4))
1991 (clobber (match_dup 5))
1992 (clobber (match_dup 6))])
1993 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1994 "")
1995
0e5a4ad8
EC
1996;; Splitter to copy result of MADD to a general register
1997(define_split
1998 [(set (match_operand:SI 0 "register_operand" "")
1999 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2000 (match_operand:SI 2 "register_operand" ""))
2001 (match_operand:SI 3 "register_operand" "")))
2002 (clobber (match_scratch:SI 4 ""))
2003 (clobber (match_scratch:SI 5 ""))
2004 (clobber (match_scratch:SI 6 ""))
2005 (clobber (match_scratch:SI 7 ""))]
2ca2d9ee
EC
2006 "reload_completed && !TARGET_DEBUG_D_MODE
2007 && GP_REG_P (true_regnum (operands[0]))
0e5a4ad8
EC
2008 && true_regnum (operands[3]) == LO_REGNUM"
2009 [(parallel [(set (match_dup 3)
2010 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
2011 (match_dup 3)))
2012 (clobber (match_dup 4))
2013 (clobber (match_dup 5))
2014 (clobber (match_dup 6))
2015 (clobber (match_dup 7))])
2016 (set (match_dup 0) (match_dup 3))]
2017 "")
2018
cafe096b
EC
2019(define_insn "*macc"
2020 [(set (match_operand:SI 0 "register_operand" "=l,d")
2021 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
2022 (match_operand:SI 2 "register_operand" "d,d"))
2023 (match_operand:SI 3 "register_operand" "0,l")))
2024 (clobber (match_scratch:SI 4 "=h,h"))
2025 (clobber (match_scratch:SI 5 "=X,3"))
2026 (clobber (match_scratch:SI 6 "=a,a"))]
2027 "ISA_HAS_MACC"
2028 "*
2029{
2030 if (which_alternative == 1)
2031 return \"macc\\t%0,%1,%2\";
2032 else if (TARGET_MIPS5500)
2033 return \"madd\\t%1,%2\";
2034 else
2035 return \"macc\\t%.,%1,%2\";
2036}"
2037 [(set_attr "type" "imadd")
2038 (set_attr "mode" "SI")])
2039
2040;; Pattern generated by define_peephole2 below
2041(define_insn "*macc2"
2042 [(set (match_operand:SI 0 "register_operand" "=l")
2043 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2044 (match_operand:SI 2 "register_operand" "d"))
2045 (match_dup 0)))
2046 (set (match_operand:SI 3 "register_operand" "=d")
2047 (plus:SI (mult:SI (match_dup 1)
2048 (match_dup 2))
2049 (match_dup 0)))
2050 (clobber (match_scratch:SI 4 "=h"))
2051 (clobber (match_scratch:SI 5 "=a"))]
2052 "ISA_HAS_MACC && reload_completed"
2053 "macc\\t%3,%1,%2"
2054 [(set_attr "type" "imadd")
2055 (set_attr "mode" "SI")])
2056
2057;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
2058;;
2059;; Operand 0: LO
2060;; Operand 1: GPR (1st multiplication operand)
2061;; Operand 2: GPR (2nd multiplication operand)
2062;; Operand 3: HI
2063;; Operand 4: HILO
2064;; Operand 5: GPR (destination)
2065(define_peephole2
2066 [(parallel
2067 [(set (match_operand:SI 0 "register_operand" "")
2068 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2069 (match_operand:SI 2 "register_operand" ""))
2070 (match_dup 0)))
2071 (clobber (match_operand:SI 3 "register_operand" ""))
2072 (clobber (scratch:SI))
2073 (clobber (match_operand:SI 4 "register_operand" ""))])
2074 (set (match_operand:SI 5 "register_operand" "")
2075 (match_dup 0))]
2076 "ISA_HAS_MACC
2077 && true_regnum (operands[0]) == LO_REGNUM
2078 && GP_REG_P (true_regnum (operands[5]))"
2079 [(parallel [(set (match_dup 0)
2080 (plus:SI (mult:SI (match_dup 1)
2081 (match_dup 2))
2082 (match_dup 0)))
2083 (set (match_dup 5)
2084 (plus:SI (mult:SI (match_dup 1)
2085 (match_dup 2))
2086 (match_dup 0)))
2087 (clobber (match_dup 3))
2088 (clobber (match_dup 4))])]
2089 "")
2090
2091;; When we have a three-address multiplication instruction, it should
2092;; be faster to do a separate multiply and add, rather than moving
2093;; something into LO in order to use a macc instruction.
2094;;
2095;; This peephole needs a scratch register to cater for the case when one
2096;; of the multiplication operands is the same as the destination.
2097;;
2098;; Operand 0: GPR (scratch)
2099;; Operand 1: LO
2100;; Operand 2: GPR (addend)
2101;; Operand 3: GPR (destination)
2102;; Operand 4: GPR (1st multiplication operand)
2103;; Operand 5: GPR (2nd multiplication operand)
2104;; Operand 6: HI
2105;; Operand 7: HILO
2106(define_peephole2
2107 [(match_scratch:SI 0 "d")
2108 (set (match_operand:SI 1 "register_operand" "")
2109 (match_operand:SI 2 "register_operand" ""))
2110 (match_dup 0)
2111 (parallel
2112 [(set (match_operand:SI 3 "register_operand" "")
2113 (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
2114 (match_operand:SI 5 "register_operand" ""))
2115 (match_dup 1)))
2116 (clobber (match_operand:SI 6 "register_operand" ""))
2117 (clobber (match_dup 1))
2118 (clobber (match_operand:SI 7 "register_operand" ""))])]
2119 "ISA_HAS_MACC && GENERATE_MULT3_SI
2120 && true_regnum (operands[1]) == LO_REGNUM
2121 && peep2_reg_dead_p (2, operands[1])
2122 && GP_REG_P (true_regnum (operands[3]))"
2123 [(parallel [(set (match_dup 0)
2124 (mult:SI (match_dup 4)
2125 (match_dup 5)))
2126 (clobber (match_dup 6))
2127 (clobber (match_dup 1))
2128 (clobber (match_dup 7))])
2129 (set (match_dup 3)
2130 (plus:SI (match_dup 0)
2131 (match_dup 2)))]
2132 "")
2133
2134;; Same as above, except LO is the initial target of the macc.
2135;;
2136;; Operand 0: GPR (scratch)
2137;; Operand 1: LO
2138;; Operand 2: GPR (addend)
2139;; Operand 3: GPR (1st multiplication operand)
2140;; Operand 4: GPR (2nd multiplication operand)
2141;; Operand 5: HI
2142;; Operand 6: HILO
2143;; Operand 7: GPR (destination)
2144(define_peephole2
2145 [(match_scratch:SI 0 "d")
2146 (set (match_operand:SI 1 "register_operand" "")
2147 (match_operand:SI 2 "register_operand" ""))
2148 (match_dup 0)
2149 (parallel
2150 [(set (match_dup 1)
2151 (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
2152 (match_operand:SI 4 "register_operand" ""))
2153 (match_dup 1)))
2154 (clobber (match_operand:SI 5 "register_operand" ""))
2155 (clobber (scratch:SI))
2156 (clobber (match_operand:SI 6 "register_operand" ""))])
2157 (match_dup 0)
2158 (set (match_operand:SI 7 "register_operand" "")
2159 (match_dup 1))]
2160 "ISA_HAS_MACC && GENERATE_MULT3_SI
2161 && true_regnum (operands[1]) == LO_REGNUM
2162 && peep2_reg_dead_p (3, operands[1])
2163 && GP_REG_P (true_regnum (operands[7]))"
2164 [(parallel [(set (match_dup 0)
2165 (mult:SI (match_dup 3)
2166 (match_dup 4)))
2167 (clobber (match_dup 5))
2168 (clobber (match_dup 1))
2169 (clobber (match_dup 6))])
2170 (set (match_dup 7)
2171 (plus:SI (match_dup 0)
2172 (match_dup 2)))]
2173 "")
2174
0e5a4ad8
EC
2175(define_insn "*mul_sub_si"
2176 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
2177 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
2178 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
2179 (match_operand:SI 3 "register_operand" "d,d,d"))))
2180 (clobber (match_scratch:SI 4 "=h,h,h"))
cafe096b 2181 (clobber (match_scratch:SI 5 "=X,1,l"))
0e5a4ad8
EC
2182 (clobber (match_scratch:SI 6 "=a,a,a"))
2183 (clobber (match_scratch:SI 7 "=X,X,d"))]
2184 "ISA_HAS_MADD_MSUB"
2185 "*
2186{
2187 if (which_alternative != 0)
2188 return \"#\";
2189 return \"msub\\t%2,%3\";
2190}"
1d4047e0 2191 [(set_attr "type" "imadd,multi,multi")
0e5a4ad8
EC
2192 (set_attr "mode" "SI")
2193 (set_attr "length" "4,8,8")])
2194
2195;; Split the above insn if we failed to get LO allocated.
2196(define_split
2197 [(set (match_operand:SI 0 "register_operand" "")
2198 (minus:SI (match_operand:SI 1 "register_operand" "")
2199 (mult:SI (match_operand:SI 2 "register_operand" "")
2200 (match_operand:SI 3 "register_operand" ""))))
2201 (clobber (match_scratch:SI 4 ""))
2202 (clobber (match_scratch:SI 5 ""))
2203 (clobber (match_scratch:SI 6 ""))
2204 (clobber (match_scratch:SI 7 ""))]
2ca2d9ee
EC
2205 "reload_completed && !TARGET_DEBUG_D_MODE
2206 && GP_REG_P (true_regnum (operands[0]))
2207 && GP_REG_P (true_regnum (operands[1]))"
0e5a4ad8
EC
2208 [(parallel [(set (match_dup 7)
2209 (mult:SI (match_dup 2) (match_dup 3)))
2210 (clobber (match_dup 4))
2211 (clobber (match_dup 5))
2212 (clobber (match_dup 6))])
2213 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
2214 "")
2215
2216;; Splitter to copy result of MSUB to a general register
2217(define_split
2218 [(set (match_operand:SI 0 "register_operand" "")
2219 (minus:SI (match_operand:SI 1 "register_operand" "")
2220 (mult:SI (match_operand:SI 2 "register_operand" "")
2221 (match_operand:SI 3 "register_operand" ""))))
2222 (clobber (match_scratch:SI 4 ""))
2223 (clobber (match_scratch:SI 5 ""))
2224 (clobber (match_scratch:SI 6 ""))
2225 (clobber (match_scratch:SI 7 ""))]
2ca2d9ee
EC
2226 "reload_completed && !TARGET_DEBUG_D_MODE
2227 && GP_REG_P (true_regnum (operands[0]))
0e5a4ad8
EC
2228 && true_regnum (operands[1]) == LO_REGNUM"
2229 [(parallel [(set (match_dup 1)
2230 (minus:SI (match_dup 1)
2231 (mult:SI (match_dup 2) (match_dup 3))))
2232 (clobber (match_dup 4))
2233 (clobber (match_dup 5))
2234 (clobber (match_dup 6))
2235 (clobber (match_dup 7))])
2236 (set (match_dup 0) (match_dup 1))]
2237 "")
2238
5ce6f47b
EC
2239(define_insn "*muls"
2240 [(set (match_operand:SI 0 "register_operand" "=l,d")
2241 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
2242 (match_operand:SI 2 "register_operand" "d,d"))))
2243 (clobber (match_scratch:SI 3 "=h,h"))
2244 (clobber (match_scratch:SI 4 "=a,a"))
2245 (clobber (match_scratch:SI 5 "=X,l"))]
cafe096b 2246 "ISA_HAS_MULS"
5ce6f47b
EC
2247 "@
2248 muls\\t$0,%1,%2
2249 muls\\t%0,%1,%2"
2250 [(set_attr "type" "imul")
2251 (set_attr "mode" "SI")])
2252
5ce6f47b 2253(define_insn "*msac"
cafe096b
EC
2254 [(set (match_operand:SI 0 "register_operand" "=l,d")
2255 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
2256 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
2257 (match_operand:SI 3 "register_operand" "d,d"))))
2258 (clobber (match_scratch:SI 4 "=h,h"))
2259 (clobber (match_scratch:SI 5 "=X,1"))
2260 (clobber (match_scratch:SI 6 "=a,a"))]
2261 "ISA_HAS_MSAC"
2262 "*
2263{
2264 if (which_alternative == 1)
2265 return \"msac\\t%0,%2,%3\";
2266 else if (TARGET_MIPS5500)
2267 return \"msub\\t%2,%3\";
2268 else
2269 return \"msac\\t$0,%2,%3\";
2270}"
2271 [(set_attr "type" "imadd")
2272 (set_attr "mode" "SI")])
053665d7 2273
46299de9
ILT
2274(define_expand "muldi3"
2275 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b 2276 (mult:DI (match_operand:DI 1 "register_operand" "d")
46299de9 2277 (match_operand:DI 2 "register_operand" "d")))
225b8835
ILT
2278 (clobber (match_scratch:DI 3 "=h"))
2279 (clobber (match_scratch:DI 4 "=a"))]
46299de9 2280 "TARGET_64BIT"
cb923660 2281
46299de9
ILT
2282 "
2283{
0e5a4ad8 2284 if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)
868e82ab 2285 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
46299de9 2286 else
868e82ab 2287 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
46299de9
ILT
2288 DONE;
2289}")
8ef30996 2290
46299de9
ILT
2291(define_insn "muldi3_internal"
2292 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b 2293 (mult:DI (match_operand:DI 1 "register_operand" "d")
46299de9 2294 (match_operand:DI 2 "register_operand" "d")))
225b8835
ILT
2295 (clobber (match_scratch:DI 3 "=h"))
2296 (clobber (match_scratch:DI 4 "=a"))]
7dac2f89 2297 "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
e7faa2f6 2298 "dmult\\t%1,%2"
8ef30996 2299 [(set_attr "type" "imul")
0ff83799 2300 (set_attr "mode" "DI")])
8ef30996 2301
868e82ab 2302(define_insn "muldi3_internal2"
bb621ad7 2303 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 2304 (mult:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 2305 (match_operand:DI 2 "register_operand" "d")))
46299de9 2306 (clobber (match_scratch:DI 3 "=h"))
225b8835
ILT
2307 (clobber (match_scratch:DI 4 "=l"))
2308 (clobber (match_scratch:DI 5 "=a"))]
0e5a4ad8 2309 "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)"
bb621ad7
JW
2310 "*
2311{
0e5a4ad8 2312 if (GENERATE_MULT3_DI)
868e82ab 2313 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
7a38df19 2314 else
868e82ab 2315 {
c5c76735 2316 rtx xoperands[10];
bb621ad7 2317
c5c76735
JL
2318 xoperands[0] = operands[0];
2319 xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
bb621ad7 2320
c5c76735
JL
2321 output_asm_insn (\"dmult\\t%1,%2\", operands);
2322 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
868e82ab 2323 }
bb621ad7
JW
2324 return \"\";
2325}"
2326 [(set_attr "type" "imul")
2327 (set_attr "mode" "DI")
868e82ab 2328 (set (attr "length")
0e5a4ad8 2329 (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
0ff83799
MM
2330 (const_int 4)
2331 (const_int 12)))]) ;; mult + mflo + delay
bb621ad7 2332
bb621ad7
JW
2333;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
2334
225b8835 2335(define_expand "mulsidi3"
46299de9 2336 [(set (match_operand:DI 0 "register_operand" "=x")
8ef30996 2337 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
46299de9 2338 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
225b8835
ILT
2339 ""
2340 "
2341{
2342 if (TARGET_64BIT)
cafe096b 2343 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
225b8835 2344 else
cafe096b 2345 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
225b8835
ILT
2346 DONE;
2347}")
2348
cafe096b
EC
2349(define_insn "mulsidi3_internal"
2350 [(set (match_operand:DI 0 "register_operand" "=x")
2351 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2352 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2353 (clobber (match_scratch:SI 3 "=a"))]
2354 "!TARGET_64BIT"
2355 "mult\\t%1,%2"
2356 [(set_attr "type" "imul")
2357 (set_attr "mode" "SI")])
2358
2359(define_insn "mulsidi3_64bit"
2360 [(set (match_operand:DI 0 "register_operand" "=a")
2361 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2362 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2363 (clobber (match_scratch:DI 3 "=l"))
2364 (clobber (match_scratch:DI 4 "=h"))]
2365 "TARGET_64BIT"
2366 "mult\\t%1,%2"
2367 [(set_attr "type" "imul")
2368 (set_attr "mode" "SI")])
2369
225b8835 2370(define_expand "umulsidi3"
46299de9 2371 [(set (match_operand:DI 0 "register_operand" "=x")
8ef30996 2372 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
46299de9 2373 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
225b8835
ILT
2374 ""
2375 "
2376{
2377 if (TARGET_64BIT)
cafe096b 2378 emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
225b8835 2379 else
cafe096b
EC
2380 emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
2381
225b8835
ILT
2382 DONE;
2383}")
2384
cafe096b
EC
2385
2386(define_insn "umulsidi3_internal"
225b8835 2387 [(set (match_operand:DI 0 "register_operand" "=x")
cafe096b
EC
2388 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2389 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2390 (clobber (match_scratch:SI 3 "=a"))]
2391 "!TARGET_64BIT"
2392 "multu\\t%1,%2"
8ef30996 2393 [(set_attr "type" "imul")
0ff83799 2394 (set_attr "mode" "SI")])
8ef30996 2395
cafe096b 2396(define_insn "umulsidi3_64bit"
225b8835 2397 [(set (match_operand:DI 0 "register_operand" "=a")
cafe096b
EC
2398 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2399 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
2400 (clobber (match_scratch:DI 3 "=l"))
2401 (clobber (match_scratch:DI 4 "=h"))]
2402 "TARGET_64BIT"
2403 "multu\\t%1,%2"
225b8835 2404 [(set_attr "type" "imul")
0ff83799 2405 (set_attr "mode" "SI")])
225b8835 2406
cafe096b
EC
2407;; Widening multiply with negation. It isn't worth using this pattern
2408;; for 64-bit code since the reload sequence for HILO_REGNUM is so long.
5ce6f47b 2409(define_insn "*muls_di"
cafe096b 2410 [(set (match_operand:DI 0 "register_operand" "=x")
5ce6f47b 2411 (neg:DI
cafe096b
EC
2412 (mult:DI
2413 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2414 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2415 (clobber (match_scratch:SI 3 "=a"))]
2416 "!TARGET_64BIT && ISA_HAS_MULS"
2417 "muls\\t$0,%1,%2"
2418 [(set_attr "type" "imul")
2419 (set_attr "length" "4")
2420 (set_attr "mode" "SI")])
2421
2422(define_insn "*umuls_di"
2423 [(set (match_operand:DI 0 "register_operand" "=x")
2424 (neg:DI
2425 (mult:DI
2426 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2427 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2428 (clobber (match_scratch:SI 3 "=a"))]
2429 "!TARGET_64BIT && ISA_HAS_MULS"
2430 "mulsu\\t$0,%1,%2"
2431 [(set_attr "type" "imul")
2432 (set_attr "length" "4")
2433 (set_attr "mode" "SI")])
2434
2435;; Not used for 64-bit code: see comment for *muls_di.
2436(define_insn "*smsac_di"
2437 [(set (match_operand:DI 0 "register_operand" "=x")
2438 (minus:DI (match_operand:DI 3 "register_operand" "0")
2439 (mult:DI
2440 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2441 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2442 (clobber (match_scratch:SI 4 "=a"))]
2443 "!TARGET_64BIT && ISA_HAS_MSAC"
5ce6f47b
EC
2444 "*
2445{
cafe096b
EC
2446 if (TARGET_MIPS5500)
2447 return \"msub\\t%1,%2\";
5ce6f47b 2448 else
cafe096b 2449 return \"msac\\t$0,%1,%2\";
5ce6f47b 2450}"
cafe096b 2451 [(set_attr "type" "imadd")
5ce6f47b
EC
2452 (set_attr "length" "4")
2453 (set_attr "mode" "SI")])
2454
cafe096b
EC
2455(define_insn "*umsac_di"
2456 [(set (match_operand:DI 0 "register_operand" "=x")
2457 (minus:DI (match_operand:DI 3 "register_operand" "0")
2458 (mult:DI
2459 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2460 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))
2461 (clobber (match_scratch:SI 4 "=a"))]
2462 "!TARGET_64BIT && ISA_HAS_MSAC"
5ce6f47b
EC
2463 "*
2464{
cafe096b
EC
2465 if (TARGET_MIPS5500)
2466 return \"msubu\\t%1,%2\";
5ce6f47b 2467 else
5ce6f47b 2468 return \"msacu\\t$0,%1,%2\";
5ce6f47b
EC
2469}"
2470 [(set_attr "type" "imadd")
2471 (set_attr "length" "4")
2472 (set_attr "mode" "SI")])
2473
cb923660 2474;; _highpart patterns
cafe096b 2475(define_expand "umulsi3_highpart"
cb923660
KR
2476 [(set (match_operand:SI 0 "register_operand" "=h")
2477 (truncate:SI
cafe096b
EC
2478 (lshiftrt:DI
2479 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2480 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2481 (const_int 32))))]
cb923660
KR
2482 ""
2483 "
2484{
cafe096b
EC
2485 if (ISA_HAS_MULHI)
2486 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
2487 operands[2]));
2488 else
2489 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
2490 operands[2]));
cb923660
KR
2491 DONE;
2492}")
2493
cafe096b 2494(define_insn "umulsi3_highpart_internal"
46299de9 2495 [(set (match_operand:SI 0 "register_operand" "=h")
903df3fe 2496 (truncate:SI
cafe096b
EC
2497 (lshiftrt:DI
2498 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2499 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2500 (const_int 32))))
2501 (clobber (match_scratch:SI 3 "=l"))
2502 (clobber (match_scratch:SI 4 "=a"))]
2503 "!ISA_HAS_MULHI"
2504 "multu\\t%1,%2"
2505 [(set_attr "type" "imul")
2506 (set_attr "mode" "SI")
2507 (set_attr "length" "4")])
2508
2509(define_insn "umulsi3_highpart_mulhi_internal"
2510 [(set (match_operand:SI 0 "register_operand" "=h,d")
2511 (truncate:SI
2512 (lshiftrt:DI
2513 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2514 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2515 (const_int 32))))
2516 (clobber (match_scratch:SI 3 "=l,l"))
2517 (clobber (match_scratch:SI 4 "=a,a"))
2518 (clobber (match_scratch:SI 5 "=X,h"))]
2519 "ISA_HAS_MULHI"
2520 "@
2521 multu\\t%1,%2
2522 mulhiu\\t%0,%1,%2"
2523 [(set_attr "type" "imul")
2524 (set_attr "mode" "SI")
2525 (set_attr "length" "4")])
2526
2527(define_insn "umulsi3_highpart_neg_mulhi_internal"
2528 [(set (match_operand:SI 0 "register_operand" "=h,d")
2529 (truncate:SI
2530 (lshiftrt:DI
2531 (neg:DI
2532 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2533 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2534 (const_int 32))))
2535 (clobber (match_scratch:SI 3 "=l,l"))
2536 (clobber (match_scratch:SI 4 "=a,a"))
2537 (clobber (match_scratch:SI 5 "=X,h"))]
2538 "ISA_HAS_MULHI"
2539 "@
2540 mulshiu\\t%.,%1,%2
2541 mulshiu\\t%0,%1,%2"
2542 [(set_attr "type" "imul")
2543 (set_attr "mode" "SI")
2544 (set_attr "length" "4")])
2545
2546(define_expand "smulsi3_highpart"
2547 [(set (match_operand:SI 0 "register_operand" "=h")
2548 (truncate:SI
2549 (lshiftrt:DI
2550 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2551 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2552 (const_int 32))))]
903df3fe 2553 ""
cb923660
KR
2554 "
2555{
cafe096b
EC
2556 if (ISA_HAS_MULHI)
2557 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
2558 operands[2]));
5ce6f47b 2559 else
cafe096b
EC
2560 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
2561 operands[2]));
cb923660
KR
2562 DONE;
2563}")
2564
cafe096b 2565(define_insn "smulsi3_highpart_internal"
cb923660
KR
2566 [(set (match_operand:SI 0 "register_operand" "=h")
2567 (truncate:SI
cafe096b
EC
2568 (lshiftrt:DI
2569 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2570 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2571 (const_int 32))))
2572 (clobber (match_scratch:SI 3 "=l"))
2573 (clobber (match_scratch:SI 4 "=a"))]
2574 "!ISA_HAS_MULHI"
2575 "mult\\t%1,%2"
903df3fe 2576 [(set_attr "type" "imul")
cafe096b
EC
2577 (set_attr "mode" "SI")
2578 (set_attr "length" "4")])
48199e32 2579
cafe096b 2580(define_insn "smulsi3_highpart_mulhi_internal"
5ce6f47b
EC
2581 [(set (match_operand:SI 0 "register_operand" "=h,d")
2582 (truncate:SI
cafe096b
EC
2583 (lshiftrt:DI
2584 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2585 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2586 (const_int 32))))
2587 (clobber (match_scratch:SI 3 "=l,l"))
2588 (clobber (match_scratch:SI 4 "=a,a"))
2589 (clobber (match_scratch:SI 5 "=X,h"))]
2590 "ISA_HAS_MULHI"
2591 "@
2592 mult\\t%1,%2
2593 mulhi\\t%0,%1,%2"
2594 [(set_attr "type" "imul")
2595 (set_attr "mode" "SI")
2596 (set_attr "length" "4")])
5ce6f47b 2597
cafe096b 2598(define_insn "smulsi3_highpart_neg_mulhi_internal"
5ce6f47b
EC
2599 [(set (match_operand:SI 0 "register_operand" "=h,d")
2600 (truncate:SI
cafe096b
EC
2601 (lshiftrt:DI
2602 (neg:DI
2603 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2604 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2605 (const_int 32))))
2606 (clobber (match_scratch:SI 3 "=l,l"))
2607 (clobber (match_scratch:SI 4 "=a,a"))
2608 (clobber (match_scratch:SI 5 "=X,h"))]
2609 "ISA_HAS_MULHI"
2610 "@
2611 mulshi\\t%.,%1,%2
2612 mulshi\\t%0,%1,%2"
2613 [(set_attr "type" "imul")
2614 (set_attr "mode" "SI")])
5ce6f47b 2615
48199e32 2616(define_insn "smuldi3_highpart"
46299de9 2617 [(set (match_operand:DI 0 "register_operand" "=h")
48199e32 2618 (truncate:DI
cafe096b
EC
2619 (lshiftrt:TI
2620 (mult:TI
2621 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
2622 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
2623 (const_int 64))))
225b8835
ILT
2624 (clobber (match_scratch:DI 3 "=l"))
2625 (clobber (match_scratch:DI 4 "=a"))]
48199e32 2626 "TARGET_64BIT"
46299de9 2627 "dmult\\t%1,%2"
48199e32 2628 [(set_attr "type" "imul")
0ff83799 2629 (set_attr "mode" "DI")])
48199e32
JW
2630
2631(define_insn "umuldi3_highpart"
46299de9 2632 [(set (match_operand:DI 0 "register_operand" "=h")
48199e32 2633 (truncate:DI
cafe096b
EC
2634 (lshiftrt:TI
2635 (mult:TI
2636 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
2637 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
2638 (const_int 64))))
225b8835
ILT
2639 (clobber (match_scratch:DI 3 "=l"))
2640 (clobber (match_scratch:DI 4 "=a"))]
48199e32 2641 "TARGET_64BIT"
46299de9 2642 "dmultu\\t%1,%2"
48199e32 2643 [(set_attr "type" "imul")
0ff83799 2644 (set_attr "mode" "DI")])
48199e32 2645
cafe096b 2646
46299de9
ILT
2647;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2648;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2649
2650(define_insn "madsi"
2651 [(set (match_operand:SI 0 "register_operand" "+l")
2652 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2653 (match_operand:SI 2 "register_operand" "d"))
2654 (match_dup 0)))
225b8835
ILT
2655 (clobber (match_scratch:SI 3 "=h"))
2656 (clobber (match_scratch:SI 4 "=a"))]
cb923660 2657 "TARGET_MAD"
225b8835 2658 "mad\\t%1,%2"
1d4047e0 2659 [(set_attr "type" "imadd")
0ff83799 2660 (set_attr "mode" "SI")])
225b8835 2661
cafe096b
EC
2662;; Only use this pattern in 32-bit code: see *muls_di.
2663(define_insn "*umul_acc_di"
2664 [(set (match_operand:DI 0 "register_operand" "=x")
2665 (plus:DI
2666 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2667 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2668 (match_operand:DI 3 "register_operand" "0")))
2669 (clobber (match_scratch:SI 4 "=a"))]
2670 "(TARGET_MAD || ISA_HAS_MACC)
2671 && !TARGET_64BIT"
cb923660
KR
2672 "*
2673{
cafe096b 2674 if (TARGET_MAD)
cb923660 2675 return \"madu\\t%1,%2\";
cafe096b
EC
2676 else if (TARGET_MIPS5500)
2677 return \"maddu\\t%1,%2\";
2678 else
2679 return \"maccu\\t%.,%1,%2\";
cb923660 2680}"
cafe096b
EC
2681 [(set_attr "type" "imadd")
2682 (set_attr "mode" "SI")])
e19ff60f 2683
cafe096b
EC
2684
2685(define_insn "*smul_acc_di"
2686 [(set (match_operand:DI 0 "register_operand" "=x")
2687 (plus:DI
2688 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2689 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2690 (match_operand:DI 3 "register_operand" "0")))
2691 (clobber (match_scratch:SI 4 "=a"))]
2692 "(TARGET_MAD || ISA_HAS_MACC)
2693 && !TARGET_64BIT"
cb923660
KR
2694 "*
2695{
5ce6f47b 2696 if (TARGET_MAD)
cafe096b
EC
2697 return \"mad\\t%1,%2\";
2698 else if (TARGET_MIPS5500)
2699 return \"madd\\t%1,%2\";
cb923660 2700 else
cafe096b 2701 return \"macc\\t%.,%1,%2\";
cb923660 2702}"
cafe096b
EC
2703 [(set_attr "type" "imadd")
2704 (set_attr "mode" "SI")])
e9a25f70 2705
e19ff60f
JW
2706;; Floating point multiply accumulate instructions.
2707
2708(define_insn ""
2709 [(set (match_operand:DF 0 "register_operand" "=f")
2710 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2711 (match_operand:DF 2 "register_operand" "f"))
2712 (match_operand:DF 3 "register_operand" "f")))]
13fac94a 2713 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2714 "madd.d\\t%0,%3,%1,%2"
2715 [(set_attr "type" "fmadd")
0ff83799 2716 (set_attr "mode" "DF")])
e19ff60f
JW
2717
2718(define_insn ""
2719 [(set (match_operand:SF 0 "register_operand" "=f")
2720 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2721 (match_operand:SF 2 "register_operand" "f"))
2722 (match_operand:SF 3 "register_operand" "f")))]
13fac94a 2723 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2724 "madd.s\\t%0,%3,%1,%2"
2725 [(set_attr "type" "fmadd")
0ff83799 2726 (set_attr "mode" "SF")])
e19ff60f
JW
2727
2728(define_insn ""
2729 [(set (match_operand:DF 0 "register_operand" "=f")
2730 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2731 (match_operand:DF 2 "register_operand" "f"))
2732 (match_operand:DF 3 "register_operand" "f")))]
13fac94a 2733 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2734 "msub.d\\t%0,%3,%1,%2"
2735 [(set_attr "type" "fmadd")
0ff83799 2736 (set_attr "mode" "DF")])
e19ff60f
JW
2737
2738(define_insn ""
2739 [(set (match_operand:SF 0 "register_operand" "=f")
2740 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2741 (match_operand:SF 2 "register_operand" "f"))
2742 (match_operand:SF 3 "register_operand" "f")))]
7a38df19 2743
13fac94a 2744 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2745 "msub.s\\t%0,%3,%1,%2"
2746 [(set_attr "type" "fmadd")
0ff83799 2747 (set_attr "mode" "SF")])
e19ff60f
JW
2748
2749(define_insn ""
2750 [(set (match_operand:DF 0 "register_operand" "=f")
2751 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2752 (match_operand:DF 2 "register_operand" "f"))
2753 (match_operand:DF 3 "register_operand" "f"))))]
13fac94a 2754 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2755 "nmadd.d\\t%0,%3,%1,%2"
2756 [(set_attr "type" "fmadd")
0ff83799 2757 (set_attr "mode" "DF")])
e19ff60f
JW
2758
2759(define_insn ""
2760 [(set (match_operand:SF 0 "register_operand" "=f")
2761 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2762 (match_operand:SF 2 "register_operand" "f"))
2763 (match_operand:SF 3 "register_operand" "f"))))]
13fac94a 2764 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2765 "nmadd.s\\t%0,%3,%1,%2"
2766 [(set_attr "type" "fmadd")
0ff83799 2767 (set_attr "mode" "SF")])
e19ff60f
JW
2768
2769(define_insn ""
2770 [(set (match_operand:DF 0 "register_operand" "=f")
2771 (minus:DF (match_operand:DF 1 "register_operand" "f")
2772 (mult:DF (match_operand:DF 2 "register_operand" "f")
2773 (match_operand:DF 3 "register_operand" "f"))))]
13fac94a 2774 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2775 "nmsub.d\\t%0,%1,%2,%3"
2776 [(set_attr "type" "fmadd")
0ff83799 2777 (set_attr "mode" "DF")])
e19ff60f
JW
2778
2779(define_insn ""
2780 [(set (match_operand:SF 0 "register_operand" "=f")
2781 (minus:SF (match_operand:SF 1 "register_operand" "f")
2782 (mult:SF (match_operand:SF 2 "register_operand" "f")
2783 (match_operand:SF 3 "register_operand" "f"))))]
13fac94a 2784 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
e19ff60f
JW
2785 "nmsub.s\\t%0,%1,%2,%3"
2786 [(set_attr "type" "fmadd")
0ff83799 2787 (set_attr "mode" "SF")])
8ef30996
MM
2788\f
2789;;
2790;; ....................
2791;;
2792;; DIVISION and REMAINDER
2793;;
2794;; ....................
2795;;
2796
2797(define_insn "divdf3"
2798 [(set (match_operand:DF 0 "register_operand" "=f")
2799 (div:DF (match_operand:DF 1 "register_operand" "f")
2800 (match_operand:DF 2 "register_operand" "f")))]
46299de9 2801 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
2802 "div.d\\t%0,%1,%2"
2803 [(set_attr "type" "fdiv")
0ff83799 2804 (set_attr "mode" "DF")])
8ef30996
MM
2805
2806(define_insn "divsf3"
2807 [(set (match_operand:SF 0 "register_operand" "=f")
2808 (div:SF (match_operand:SF 1 "register_operand" "f")
2809 (match_operand:SF 2 "register_operand" "f")))]
2810 "TARGET_HARD_FLOAT"
2811 "div.s\\t%0,%1,%2"
2812 [(set_attr "type" "fdiv")
0ff83799 2813 (set_attr "mode" "SF")])
8ef30996 2814
b8eb88d0
ILT
2815(define_insn ""
2816 [(set (match_operand:DF 0 "register_operand" "=f")
2817 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2818 (match_operand:DF 2 "register_operand" "f")))]
de6c5979 2819 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0
ILT
2820 "recip.d\\t%0,%2"
2821 [(set_attr "type" "fdiv")
0ff83799 2822 (set_attr "mode" "DF")])
b8eb88d0
ILT
2823
2824(define_insn ""
2825 [(set (match_operand:SF 0 "register_operand" "=f")
2826 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2827 (match_operand:SF 2 "register_operand" "f")))]
de6c5979 2828 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0
ILT
2829 "recip.s\\t%0,%2"
2830 [(set_attr "type" "fdiv")
0ff83799 2831 (set_attr "mode" "SF")])
b8eb88d0 2832
8ef30996
MM
2833;; If optimizing, prefer the divmod functions over separate div and
2834;; mod functions, since this will allow using one instruction for both
2835;; the quotient and remainder. At present, the divmod is not moved out
2836;; of loops if it is constant within the loop, so allow -mdebugc to
2837;; use the old method of doing things.
2838
2839;; 64 is the multiply/divide hi register
2840;; 65 is the multiply/divide lo register
2841
bb621ad7
JW
2842;; ??? We can't accept constants here, because the MIPS assembler will replace
2843;; a divide by power of 2 with a shift, and then the remainder is no longer
2844;; available.
2845
08c2951c 2846(define_expand "divmodsi4"
70252580
MM
2847 [(set (match_operand:SI 0 "register_operand" "=d")
2848 (div:SI (match_operand:SI 1 "register_operand" "d")
2849 (match_operand:SI 2 "register_operand" "d")))
2850 (set (match_operand:SI 3 "register_operand" "=d")
2851 (mod:SI (match_dup 1)
2852 (match_dup 2)))
46299de9 2853 (clobber (match_scratch:SI 4 "=l"))
225b8835
ILT
2854 (clobber (match_scratch:SI 5 "=h"))
2855 (clobber (match_scratch:SI 6 "=a"))]
34b650b3 2856 "optimize"
08c2951c 2857 "
8ef30996 2858{
08c2951c
SC
2859 emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2860 operands[3]));
2861 if (!TARGET_NO_CHECK_ZERO_DIV)
2862 {
2863 emit_insn (gen_div_trap (operands[2],
1feed51c 2864 GEN_INT (0),
08c2951c
SC
2865 GEN_INT (0x7)));
2866 }
2867 if (TARGET_CHECK_RANGE_DIV)
2868 {
2869 emit_insn (gen_div_trap (operands[2],
2870 copy_to_mode_reg (SImode, GEN_INT (-1)),
2871 GEN_INT (0x6)));
2872 emit_insn (gen_div_trap (operands[2],
024c02b1
AO
2873 copy_to_mode_reg (SImode,
2874 GEN_INT
2875 (trunc_int_for_mode
2876 (BITMASK_HIGH, SImode))),
08c2951c
SC
2877 GEN_INT (0x6)));
2878 }
7a38df19 2879
08c2951c
SC
2880 DONE;
2881}")
8ef30996 2882
08c2951c
SC
2883(define_insn "divmodsi4_internal"
2884 [(set (match_operand:SI 0 "register_operand" "=l")
2885 (div:SI (match_operand:SI 1 "register_operand" "d")
2886 (match_operand:SI 2 "register_operand" "d")))
2887 (set (match_operand:SI 3 "register_operand" "=h")
2888 (mod:SI (match_dup 1)
2889 (match_dup 2)))
c77e04ae 2890 (clobber (match_scratch:SI 4 "=a"))]
08c2951c
SC
2891 "optimize"
2892 "div\\t$0,%1,%2"
8ef30996 2893 [(set_attr "type" "idiv")
0ff83799 2894 (set_attr "mode" "SI")])
bb621ad7 2895
08c2951c 2896(define_expand "divmoddi4"
bb621ad7 2897 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
2898 (div:DI (match_operand:DI 1 "register_operand" "d")
2899 (match_operand:DI 2 "register_operand" "d")))
bb621ad7
JW
2900 (set (match_operand:DI 3 "register_operand" "=d")
2901 (mod:DI (match_dup 1)
2902 (match_dup 2)))
46299de9 2903 (clobber (match_scratch:DI 4 "=l"))
225b8835
ILT
2904 (clobber (match_scratch:DI 5 "=h"))
2905 (clobber (match_scratch:DI 6 "=a"))]
bb621ad7 2906 "TARGET_64BIT && optimize"
08c2951c 2907 "
bb621ad7 2908{
08c2951c
SC
2909 emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2910 operands[3]));
2911 if (!TARGET_NO_CHECK_ZERO_DIV)
2912 {
2913 emit_insn (gen_div_trap (operands[2],
1feed51c 2914 GEN_INT (0),
08c2951c
SC
2915 GEN_INT (0x7)));
2916 }
2917 if (TARGET_CHECK_RANGE_DIV)
2918 {
2919 emit_insn (gen_div_trap (operands[2],
2920 copy_to_mode_reg (DImode, GEN_INT (-1)),
2921 GEN_INT (0x6)));
2922 emit_insn (gen_div_trap (operands[2],
024c02b1
AO
2923 copy_to_mode_reg (DImode,
2924 GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2925 GEN_INT (0x6)));
2926 }
7a38df19 2927
08c2951c
SC
2928 DONE;
2929}")
bb621ad7 2930
08c2951c
SC
2931(define_insn "divmoddi4_internal"
2932 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b
EC
2933 (div:DI (match_operand:DI 1 "register_operand" "d")
2934 (match_operand:DI 2 "register_operand" "d")))
08c2951c
SC
2935 (set (match_operand:DI 3 "register_operand" "=h")
2936 (mod:DI (match_dup 1)
2937 (match_dup 2)))
c77e04ae 2938 (clobber (match_scratch:DI 4 "=a"))]
08c2951c
SC
2939 "TARGET_64BIT && optimize"
2940 "ddiv\\t$0,%1,%2"
bb621ad7 2941 [(set_attr "type" "idiv")
0ff83799 2942 (set_attr "mode" "SI")])
8ef30996 2943
08c2951c 2944(define_expand "udivmodsi4"
70252580
MM
2945 [(set (match_operand:SI 0 "register_operand" "=d")
2946 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2947 (match_operand:SI 2 "register_operand" "d")))
2948 (set (match_operand:SI 3 "register_operand" "=d")
2949 (umod:SI (match_dup 1)
2950 (match_dup 2)))
46299de9 2951 (clobber (match_scratch:SI 4 "=l"))
225b8835
ILT
2952 (clobber (match_scratch:SI 5 "=h"))
2953 (clobber (match_scratch:SI 6 "=a"))]
34b650b3 2954 "optimize"
08c2951c 2955 "
8ef30996 2956{
08c2951c
SC
2957 emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2958 operands[3]));
2959 if (!TARGET_NO_CHECK_ZERO_DIV)
2960 {
2961 emit_insn (gen_div_trap (operands[2],
1feed51c 2962 GEN_INT (0),
08c2951c
SC
2963 GEN_INT (0x7)));
2964 }
7a38df19 2965
08c2951c
SC
2966 DONE;
2967}")
8ef30996 2968
08c2951c
SC
2969(define_insn "udivmodsi4_internal"
2970 [(set (match_operand:SI 0 "register_operand" "=l")
2971 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2972 (match_operand:SI 2 "register_operand" "d")))
2973 (set (match_operand:SI 3 "register_operand" "=h")
2974 (umod:SI (match_dup 1)
2975 (match_dup 2)))
c77e04ae 2976 (clobber (match_scratch:SI 4 "=a"))]
08c2951c
SC
2977 "optimize"
2978 "divu\\t$0,%1,%2"
8ef30996 2979 [(set_attr "type" "idiv")
0ff83799 2980 (set_attr "mode" "SI")])
bb621ad7 2981
08c2951c 2982(define_expand "udivmoddi4"
bb621ad7 2983 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
2984 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2985 (match_operand:DI 2 "register_operand" "d")))
bb621ad7
JW
2986 (set (match_operand:DI 3 "register_operand" "=d")
2987 (umod:DI (match_dup 1)
2988 (match_dup 2)))
46299de9 2989 (clobber (match_scratch:DI 4 "=l"))
225b8835
ILT
2990 (clobber (match_scratch:DI 5 "=h"))
2991 (clobber (match_scratch:DI 6 "=a"))]
bb621ad7 2992 "TARGET_64BIT && optimize"
08c2951c 2993 "
bb621ad7 2994{
08c2951c
SC
2995 emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2996 operands[3]));
2997 if (!TARGET_NO_CHECK_ZERO_DIV)
2998 {
2999 emit_insn (gen_div_trap (operands[2],
1feed51c 3000 GEN_INT (0),
08c2951c
SC
3001 GEN_INT (0x7)));
3002 }
7a38df19 3003
08c2951c
SC
3004 DONE;
3005}")
bb621ad7 3006
08c2951c
SC
3007(define_insn "udivmoddi4_internal"
3008 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b
EC
3009 (udiv:DI (match_operand:DI 1 "register_operand" "d")
3010 (match_operand:DI 2 "register_operand" "d")))
08c2951c
SC
3011 (set (match_operand:DI 3 "register_operand" "=h")
3012 (umod:DI (match_dup 1)
3013 (match_dup 2)))
c77e04ae 3014 (clobber (match_scratch:DI 4 "=a"))]
08c2951c
SC
3015 "TARGET_64BIT && optimize"
3016 "ddivu\\t$0,%1,%2"
3017 [(set_attr "type" "idiv")
0ff83799 3018 (set_attr "mode" "SI")])
08c2951c
SC
3019
3020;; Division trap
bb621ad7 3021
aa7ecb4a 3022(define_expand "div_trap"
08c2951c 3023 [(trap_if (eq (match_operand 0 "register_operand" "d")
def72bd2 3024 (match_operand 1 "true_reg_or_0_operand" "dJ"))
08c2951c
SC
3025 (match_operand 2 "immediate_operand" ""))]
3026 ""
aa7ecb4a
GRK
3027 "
3028{
3029 if (TARGET_MIPS16)
3030 emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
3031 else
3032 emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
3033 DONE;
3034}")
3035
3036(define_insn "div_trap_normal"
8f8b5612
GK
3037 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
3038 (match_operand 1 "true_reg_or_0_operand" "d,J"))
aa7ecb4a
GRK
3039 (match_operand 2 "immediate_operand" ""))]
3040 "!TARGET_MIPS16"
08c2951c
SC
3041 "*
3042{
3043 rtx link;
3044 int have_dep_anti = 0;
3045
3046 /* For divmod if one division is not needed then we don't need an extra
3047 divide by zero trap, which is anti dependent on previous trap */
3048 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
3049
3050 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
487f99d2 3051 && GET_CODE (XEXP (link, 0)) == INSN
08c2951c 3052 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
8f8b5612 3053 && which_alternative == 1)
08c2951c
SC
3054 have_dep_anti = 1;
3055 if (! have_dep_anti)
b151501e
JL
3056 {
3057 if (GENERATE_BRANCHLIKELY)
3058 {
8f8b5612 3059 if (which_alternative == 1)
efa3896a 3060 return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e 3061 else
efa3896a 3062 return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e
JL
3063 }
3064 else
3065 {
8f8b5612 3066 if (which_alternative == 1)
efa3896a 3067 return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e 3068 else
efa3896a 3069 return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e
JL
3070 }
3071 }
8da31fc1 3072 return \"\";
bb621ad7 3073}"
08c2951c 3074 [(set_attr "type" "unknown")
0ff83799 3075 (set_attr "length" "12")])
aa7ecb4a
GRK
3076
3077
3078;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
3079
3080(define_insn "div_trap_mips16"
8f8b5612
GK
3081 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
3082 (match_operand 1 "true_reg_or_0_operand" "d,J"))
aa7ecb4a
GRK
3083 (match_operand 2 "immediate_operand" ""))
3084 (clobber (reg:SI 24))]
3085 "TARGET_MIPS16"
3086 "*
3087{
3088 rtx link;
3089 int have_dep_anti = 0;
3090
3091 /* For divmod if one division is not needed then we don't need an extra
3092 divide by zero trap, which is anti dependent on previous trap */
3093 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
3094
3095 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
487f99d2 3096 && GET_CODE (XEXP (link, 0)) == INSN
aa7ecb4a 3097 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
8f8b5612 3098 && which_alternative == 1)
aa7ecb4a
GRK
3099 have_dep_anti = 1;
3100 if (! have_dep_anti)
3101 {
987ba558 3102 /* No branch delay slots on mips16. */
8f8b5612 3103 if (which_alternative == 1)
efa3896a 3104 return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
aa7ecb4a 3105 else
efa3896a 3106 return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
aa7ecb4a
GRK
3107 }
3108 return \"\";
3109}"
3110 [(set_attr "type" "unknown")
0ff83799 3111 (set_attr "length" "12")])
8ef30996 3112
7e07e3ba 3113(define_expand "divsi3"
08c2951c 3114 [(set (match_operand:SI 0 "register_operand" "=l")
8ef30996 3115 (div:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
3116 (match_operand:SI 2 "register_operand" "d")))
3117 (clobber (match_scratch:SI 3 "=h"))
3118 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 3119 "!optimize"
7e07e3ba
GK
3120 "
3121{
08c2951c 3122 emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
cafe096b 3123
08c2951c
SC
3124 if (!TARGET_NO_CHECK_ZERO_DIV)
3125 {
3126 emit_insn (gen_div_trap (operands[2],
1feed51c 3127 GEN_INT (0),
08c2951c
SC
3128 GEN_INT (0x7)));
3129 }
3130 if (TARGET_CHECK_RANGE_DIV)
3131 {
3132 emit_insn (gen_div_trap (operands[2],
3133 copy_to_mode_reg (SImode, GEN_INT (-1)),
3134 GEN_INT (0x6)));
3135 emit_insn (gen_div_trap (operands[2],
024c02b1
AO
3136 copy_to_mode_reg (SImode,
3137 GEN_INT
3138 (trunc_int_for_mode
3139 (BITMASK_HIGH, SImode))),
08c2951c
SC
3140 GEN_INT (0x6)));
3141 }
7a38df19 3142
08c2951c 3143 DONE;
7e07e3ba
GK
3144}")
3145
3146(define_insn "divsi3_internal"
08c2951c 3147 [(set (match_operand:SI 0 "register_operand" "=l")
7e07e3ba 3148 (div:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
3149 (match_operand:SI 2 "nonmemory_operand" "di")))
3150 (clobber (match_scratch:SI 3 "=h"))
3151 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3152 "!optimize"
08c2951c 3153 "div\\t$0,%1,%2"
8ef30996 3154 [(set_attr "type" "idiv")
0ff83799 3155 (set_attr "mode" "SI")])
8ef30996 3156
7e07e3ba 3157(define_expand "divdi3"
08c2951c 3158 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b
EC
3159 (div:DI (match_operand:DI 1 "register_operand" "d")
3160 (match_operand:DI 2 "register_operand" "d")))
08c2951c
SC
3161 (clobber (match_scratch:DI 3 "=h"))
3162 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 3163 "TARGET_64BIT && !optimize"
7e07e3ba
GK
3164 "
3165{
08c2951c
SC
3166 emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
3167 if (!TARGET_NO_CHECK_ZERO_DIV)
3168 {
3169 emit_insn (gen_div_trap (operands[2],
1feed51c 3170 GEN_INT (0),
08c2951c
SC
3171 GEN_INT (0x7)));
3172 }
3173 if (TARGET_CHECK_RANGE_DIV)
3174 {
3175 emit_insn (gen_div_trap (operands[2],
3176 copy_to_mode_reg (DImode, GEN_INT (-1)),
3177 GEN_INT (0x6)));
3178 emit_insn (gen_div_trap (operands[2],
024c02b1
AO
3179 copy_to_mode_reg (DImode,
3180 GEN_INT (BITMASK_HIGH)),
08c2951c
SC
3181 GEN_INT (0x6)));
3182 }
7a38df19 3183
08c2951c 3184 DONE;
7e07e3ba
GK
3185}")
3186
3187(define_insn "divdi3_internal"
08c2951c 3188 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b
EC
3189 (div:DI (match_operand:DI 1 "register_operand" "d")
3190 (match_operand:DI 2 "nonmemory_operand" "di")))
08c2951c
SC
3191 (clobber (match_scratch:SI 3 "=h"))
3192 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3193 "TARGET_64BIT && !optimize"
08c2951c 3194 "ddiv\\t$0,%1,%2"
bb621ad7 3195 [(set_attr "type" "idiv")
0ff83799 3196 (set_attr "mode" "DI")])
bb621ad7 3197
7e07e3ba 3198(define_expand "modsi3"
08c2951c 3199 [(set (match_operand:SI 0 "register_operand" "=h")
8ef30996 3200 (mod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c 3201 (match_operand:SI 2 "register_operand" "d")))
46299de9 3202 (clobber (match_scratch:SI 3 "=l"))
08c2951c 3203 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 3204 "!optimize"
7e07e3ba
GK
3205 "
3206{
08c2951c
SC
3207 emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
3208 if (!TARGET_NO_CHECK_ZERO_DIV)
3209 {
3210 emit_insn (gen_div_trap (operands[2],
1feed51c 3211 GEN_INT (0),
08c2951c
SC
3212 GEN_INT (0x7)));
3213 }
3214 if (TARGET_CHECK_RANGE_DIV)
3215 {
3216 emit_insn (gen_div_trap (operands[2],
3217 copy_to_mode_reg (SImode, GEN_INT (-1)),
3218 GEN_INT (0x6)));
3219 emit_insn (gen_div_trap (operands[2],
024c02b1
AO
3220 copy_to_mode_reg (SImode,
3221 GEN_INT
3222 (trunc_int_for_mode
3223 (BITMASK_HIGH, SImode))),
08c2951c
SC
3224 GEN_INT (0x6)));
3225 }
7a38df19 3226
08c2951c 3227 DONE;
7e07e3ba
GK
3228}")
3229
3230(define_insn "modsi3_internal"
08c2951c 3231 [(set (match_operand:SI 0 "register_operand" "=h")
7e07e3ba 3232 (mod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
3233 (match_operand:SI 2 "nonmemory_operand" "di")))
3234 (clobber (match_scratch:SI 3 "=l"))
3235 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3236 "!optimize"
08c2951c 3237 "div\\t$0,%1,%2"
8ef30996 3238 [(set_attr "type" "idiv")
0ff83799 3239 (set_attr "mode" "SI")])
bb621ad7 3240
7e07e3ba 3241(define_expand "moddi3"
08c2951c 3242 [(set (match_operand:DI 0 "register_operand" "=h")
cafe096b
EC
3243 (mod:DI (match_operand:DI 1 "register_operand" "d")
3244 (match_operand:DI 2 "register_operand" "d")))
46299de9 3245 (clobber (match_scratch:DI 3 "=l"))
08c2951c 3246 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 3247 "TARGET_64BIT && !optimize"
7e07e3ba
GK
3248 "
3249{
08c2951c
SC
3250 emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
3251 if (!TARGET_NO_CHECK_ZERO_DIV)
3252 {
3253 emit_insn (gen_div_trap (operands[2],
1feed51c 3254 GEN_INT (0),
08c2951c
SC
3255 GEN_INT (0x7)));
3256 }
3257 if (TARGET_CHECK_RANGE_DIV)
3258 {
3259 emit_insn (gen_div_trap (operands[2],
3260 copy_to_mode_reg (DImode, GEN_INT (-1)),
3261 GEN_INT (0x6)));
3262 emit_insn (gen_div_trap (operands[2],
024c02b1
AO
3263 copy_to_mode_reg (DImode,
3264 GEN_INT (BITMASK_HIGH)),
08c2951c
SC
3265 GEN_INT (0x6)));
3266 }
7a38df19 3267
08c2951c 3268 DONE;
7e07e3ba
GK
3269}")
3270
3271(define_insn "moddi3_internal"
08c2951c 3272 [(set (match_operand:DI 0 "register_operand" "=h")
cafe096b
EC
3273 (mod:DI (match_operand:DI 1 "register_operand" "d")
3274 (match_operand:DI 2 "nonmemory_operand" "di")))
08c2951c
SC
3275 (clobber (match_scratch:SI 3 "=l"))
3276 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3277 "TARGET_64BIT && !optimize"
08c2951c 3278 "ddiv\\t$0,%1,%2"
bb621ad7 3279 [(set_attr "type" "idiv")
0ff83799 3280 (set_attr "mode" "DI")])
8ef30996 3281
7e07e3ba 3282(define_expand "udivsi3"
08c2951c 3283 [(set (match_operand:SI 0 "register_operand" "=l")
8ef30996 3284 (udiv:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
3285 (match_operand:SI 2 "register_operand" "d")))
3286 (clobber (match_scratch:SI 3 "=h"))
3287 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 3288 "!optimize"
7e07e3ba
GK
3289 "
3290{
08c2951c
SC
3291 emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
3292 if (!TARGET_NO_CHECK_ZERO_DIV)
3293 {
3294 emit_insn (gen_div_trap (operands[2],
1feed51c 3295 GEN_INT (0),
08c2951c
SC
3296 GEN_INT (0x7)));
3297 }
7a38df19 3298
08c2951c 3299 DONE;
7e07e3ba
GK
3300}")
3301
3302(define_insn "udivsi3_internal"
08c2951c 3303 [(set (match_operand:SI 0 "register_operand" "=l")
7e07e3ba 3304 (udiv:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
3305 (match_operand:SI 2 "nonmemory_operand" "di")))
3306 (clobber (match_scratch:SI 3 "=h"))
3307 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3308 "!optimize"
08c2951c 3309 "divu\\t$0,%1,%2"
8ef30996 3310 [(set_attr "type" "idiv")
0ff83799 3311 (set_attr "mode" "SI")])
bb621ad7 3312
7e07e3ba 3313(define_expand "udivdi3"
08c2951c 3314 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b
EC
3315 (udiv:DI (match_operand:DI 1 "register_operand" "d")
3316 (match_operand:DI 2 "register_operand" "di")))
08c2951c
SC
3317 (clobber (match_scratch:DI 3 "=h"))
3318 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 3319 "TARGET_64BIT && !optimize"
7e07e3ba
GK
3320 "
3321{
08c2951c
SC
3322 emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
3323 if (!TARGET_NO_CHECK_ZERO_DIV)
3324 {
3325 emit_insn (gen_div_trap (operands[2],
1feed51c 3326 GEN_INT (0),
08c2951c
SC
3327 GEN_INT (0x7)));
3328 }
7a38df19 3329
08c2951c 3330 DONE;
7e07e3ba
GK
3331}")
3332
3333(define_insn "udivdi3_internal"
08c2951c 3334 [(set (match_operand:DI 0 "register_operand" "=l")
cafe096b
EC
3335 (udiv:DI (match_operand:DI 1 "register_operand" "d")
3336 (match_operand:DI 2 "nonmemory_operand" "di")))
08c2951c
SC
3337 (clobber (match_scratch:SI 3 "=h"))
3338 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3339 "TARGET_64BIT && !optimize"
08c2951c 3340 "ddivu\\t$0,%1,%2"
bb621ad7 3341 [(set_attr "type" "idiv")
0ff83799 3342 (set_attr "mode" "DI")])
8ef30996 3343
7e07e3ba 3344(define_expand "umodsi3"
08c2951c 3345 [(set (match_operand:SI 0 "register_operand" "=h")
8ef30996 3346 (umod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c 3347 (match_operand:SI 2 "register_operand" "d")))
46299de9 3348 (clobber (match_scratch:SI 3 "=l"))
08c2951c 3349 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 3350 "!optimize"
7e07e3ba
GK
3351 "
3352{
08c2951c
SC
3353 emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
3354 if (!TARGET_NO_CHECK_ZERO_DIV)
3355 {
3356 emit_insn (gen_div_trap (operands[2],
1feed51c 3357 GEN_INT (0),
08c2951c
SC
3358 GEN_INT (0x7)));
3359 }
7a38df19 3360
08c2951c 3361 DONE;
7e07e3ba
GK
3362}")
3363
3364(define_insn "umodsi3_internal"
08c2951c 3365 [(set (match_operand:SI 0 "register_operand" "=h")
7e07e3ba 3366 (umod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
3367 (match_operand:SI 2 "nonmemory_operand" "di")))
3368 (clobber (match_scratch:SI 3 "=l"))
3369 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3370 "!optimize"
08c2951c 3371 "divu\\t$0,%1,%2"
8ef30996 3372 [(set_attr "type" "idiv")
0ff83799 3373 (set_attr "mode" "SI")])
bb621ad7 3374
7e07e3ba 3375(define_expand "umoddi3"
08c2951c 3376 [(set (match_operand:DI 0 "register_operand" "=h")
cafe096b
EC
3377 (umod:DI (match_operand:DI 1 "register_operand" "d")
3378 (match_operand:DI 2 "register_operand" "di")))
46299de9 3379 (clobber (match_scratch:DI 3 "=l"))
08c2951c 3380 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 3381 "TARGET_64BIT && !optimize"
7e07e3ba
GK
3382 "
3383{
08c2951c
SC
3384 emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
3385 if (!TARGET_NO_CHECK_ZERO_DIV)
3386 {
3387 emit_insn (gen_div_trap (operands[2],
1feed51c 3388 GEN_INT (0),
08c2951c
SC
3389 GEN_INT (0x7)));
3390 }
7a38df19 3391
08c2951c 3392 DONE;
7e07e3ba
GK
3393}")
3394
3395(define_insn "umoddi3_internal"
08c2951c 3396 [(set (match_operand:DI 0 "register_operand" "=h")
cafe096b
EC
3397 (umod:DI (match_operand:DI 1 "register_operand" "d")
3398 (match_operand:DI 2 "nonmemory_operand" "di")))
08c2951c
SC
3399 (clobber (match_scratch:SI 3 "=l"))
3400 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 3401 "TARGET_64BIT && !optimize"
08c2951c 3402 "ddivu\\t$0,%1,%2"
bb621ad7 3403 [(set_attr "type" "idiv")
0ff83799 3404 (set_attr "mode" "DI")])
8ef30996
MM
3405\f
3406;;
3407;; ....................
3408;;
3409;; SQUARE ROOT
3410;;
3411;; ....................
3412
3413(define_insn "sqrtdf2"
3414 [(set (match_operand:DF 0 "register_operand" "=f")
3415 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
46299de9 3416 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
8ef30996 3417 "sqrt.d\\t%0,%1"
bb621ad7 3418 [(set_attr "type" "fsqrt")
0ff83799 3419 (set_attr "mode" "DF")])
8ef30996
MM
3420
3421(define_insn "sqrtsf2"
3422 [(set (match_operand:SF 0 "register_operand" "=f")
3423 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3424 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
3425 "sqrt.s\\t%0,%1"
bb621ad7 3426 [(set_attr "type" "fsqrt")
0ff83799 3427 (set_attr "mode" "SF")])
8ef30996 3428
b8eb88d0
ILT
3429(define_insn ""
3430 [(set (match_operand:DF 0 "register_operand" "=f")
3431 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
3432 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
de6c5979 3433 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0 3434 "rsqrt.d\\t%0,%2"
5ce6f47b 3435 [(set_attr "type" "frsqrt")
0ff83799 3436 (set_attr "mode" "DF")])
b8eb88d0
ILT
3437
3438(define_insn ""
3439 [(set (match_operand:SF 0 "register_operand" "=f")
3440 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
3441 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
de6c5979 3442 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0 3443 "rsqrt.s\\t%0,%2"
5ce6f47b 3444 [(set_attr "type" "frsqrt")
0ff83799 3445 (set_attr "mode" "SF")])
b8eb88d0 3446
8ef30996
MM
3447\f
3448;;
3449;; ....................
3450;;
3451;; ABSOLUTE VALUE
3452;;
3453;; ....................
3454
3455;; Do not use the integer abs macro instruction, since that signals an
3456;; exception on -2147483648 (sigh).
3457
3458(define_insn "abssi2"
3459 [(set (match_operand:SI 0 "register_operand" "=d")
3460 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2bcb2ab3 3461 "!TARGET_MIPS16"
8ef30996
MM
3462 "*
3463{
3464 dslots_jump_total++;
3465 dslots_jump_filled++;
3466 operands[2] = const0_rtx;
3467
bb621ad7
JW
3468 if (REGNO (operands[0]) == REGNO (operands[1]))
3469 {
e9a25f70 3470 if (GENERATE_BRANCHLIKELY)
efa3896a 3471 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
bb621ad7 3472 else
efa3896a 3473 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
7a38df19 3474 }
bb621ad7 3475 else
efa3896a 3476 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
8ef30996
MM
3477}"
3478 [(set_attr "type" "multi")
3479 (set_attr "mode" "SI")
0ff83799 3480 (set_attr "length" "12")])
8ef30996 3481
bb621ad7
JW
3482(define_insn "absdi2"
3483 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 3484 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2bcb2ab3 3485 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3486 "*
3487{
404e4854 3488 unsigned int regno1;
bb621ad7
JW
3489 dslots_jump_total++;
3490 dslots_jump_filled++;
3491 operands[2] = const0_rtx;
7a38df19 3492
12a345cd
CP
3493 if (GET_CODE (operands[1]) == REG)
3494 regno1 = REGNO (operands[1]);
7a38df19 3495 else
12a345cd 3496 regno1 = REGNO (XEXP (operands[1], 0));
bb621ad7 3497
12a345cd 3498 if (REGNO (operands[0]) == regno1)
efa3896a 3499 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
bb621ad7 3500 else
efa3896a 3501 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
bb621ad7
JW
3502}"
3503 [(set_attr "type" "multi")
3504 (set_attr "mode" "DI")
0ff83799 3505 (set_attr "length" "12")])
bb621ad7 3506
8ef30996
MM
3507(define_insn "absdf2"
3508 [(set (match_operand:DF 0 "register_operand" "=f")
3509 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
46299de9 3510 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
3511 "abs.d\\t%0,%1"
3512 [(set_attr "type" "fabs")
0ff83799 3513 (set_attr "mode" "DF")])
8ef30996
MM
3514
3515(define_insn "abssf2"
3516 [(set (match_operand:SF 0 "register_operand" "=f")
3517 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3518 "TARGET_HARD_FLOAT"
3519 "abs.s\\t%0,%1"
3520 [(set_attr "type" "fabs")
0ff83799 3521 (set_attr "mode" "SF")])
8ef30996
MM
3522
3523\f
3524;;
3525;; ....................
3526;;
3527;; FIND FIRST BIT INSTRUCTION
3528;;
3529;; ....................
3530;;
3531
3532(define_insn "ffssi2"
3533 [(set (match_operand:SI 0 "register_operand" "=&d")
3534 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
7d87c851
MM
3535 (clobber (match_scratch:SI 2 "=&d"))
3536 (clobber (match_scratch:SI 3 "=&d"))]
2bcb2ab3 3537 "!TARGET_MIPS16"
8ef30996
MM
3538 "*
3539{
3540 dslots_jump_total += 2;
3541 dslots_jump_filled += 2;
3542 operands[4] = const0_rtx;
3543
3544 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3545 return \"%(\\
3546move\\t%0,%z4\\n\\
3547\\tbeq\\t%1,%z4,2f\\n\\
efa3896a 3548%~1:\\tand\\t%2,%1,0x0001\\n\\
8ef30996
MM
3549\\taddu\\t%0,%0,1\\n\\
3550\\tbeq\\t%2,%z4,1b\\n\\
3551\\tsrl\\t%1,%1,1\\n\\
efa3896a 3552%~2:%)\";
8ef30996
MM
3553
3554 return \"%(\\
3555move\\t%0,%z4\\n\\
3556\\tmove\\t%3,%1\\n\\
3557\\tbeq\\t%3,%z4,2f\\n\\
efa3896a 3558%~1:\\tand\\t%2,%3,0x0001\\n\\
8ef30996
MM
3559\\taddu\\t%0,%0,1\\n\\
3560\\tbeq\\t%2,%z4,1b\\n\\
3561\\tsrl\\t%3,%3,1\\n\\
efa3896a 3562%~2:%)\";
8ef30996
MM
3563}"
3564 [(set_attr "type" "multi")
3565 (set_attr "mode" "SI")
0ff83799 3566 (set_attr "length" "12")])
8ef30996 3567
bb621ad7
JW
3568(define_insn "ffsdi2"
3569 [(set (match_operand:DI 0 "register_operand" "=&d")
cafe096b 3570 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
bb621ad7
JW
3571 (clobber (match_scratch:DI 2 "=&d"))
3572 (clobber (match_scratch:DI 3 "=&d"))]
2bcb2ab3 3573 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3574 "*
3575{
3576 dslots_jump_total += 2;
3577 dslots_jump_filled += 2;
3578 operands[4] = const0_rtx;
3579
3580 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
3581 return \"%(\\
3582move\\t%0,%z4\\n\\
3583\\tbeq\\t%1,%z4,2f\\n\\
efa3896a 3584%~1:\\tand\\t%2,%1,0x0001\\n\\
bb621ad7
JW
3585\\tdaddu\\t%0,%0,1\\n\\
3586\\tbeq\\t%2,%z4,1b\\n\\
3587\\tdsrl\\t%1,%1,1\\n\\
efa3896a 3588%~2:%)\";
bb621ad7
JW
3589
3590 return \"%(\\
3591move\\t%0,%z4\\n\\
3592\\tmove\\t%3,%1\\n\\
3593\\tbeq\\t%3,%z4,2f\\n\\
efa3896a 3594%~1:\\tand\\t%2,%3,0x0001\\n\\
bb621ad7
JW
3595\\tdaddu\\t%0,%0,1\\n\\
3596\\tbeq\\t%2,%z4,1b\\n\\
3597\\tdsrl\\t%3,%3,1\\n\\
efa3896a 3598%~2:%)\";
bb621ad7
JW
3599}"
3600 [(set_attr "type" "multi")
3601 (set_attr "mode" "DI")
0ff83799 3602 (set_attr "length" "24")])
bb621ad7 3603
8ef30996
MM
3604\f
3605;;
3606;; ....................
3607;;
3608;; NEGATION and ONE'S COMPLEMENT
3609;;
3610;; ....................
3611
3612(define_insn "negsi2"
3613 [(set (match_operand:SI 0 "register_operand" "=d")
3614 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3615 ""
3616 "*
3617{
2bcb2ab3
GK
3618 if (TARGET_MIPS16)
3619 return \"neg\\t%0,%1\";
8ef30996
MM
3620 operands[2] = const0_rtx;
3621 return \"subu\\t%0,%z2,%1\";
3622}"
3623 [(set_attr "type" "arith")
0ff83799 3624 (set_attr "mode" "SI")])
8ef30996 3625
e7d7b3dc 3626(define_expand "negdi2"
8ef30996 3627 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 3628 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8ef30996 3629 (clobber (match_dup 2))])]
2bcb2ab3 3630 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
bb621ad7
JW
3631 "
3632{
3633 if (TARGET_64BIT)
3634 {
3635 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3636 DONE;
3637 }
3638
3639 operands[2] = gen_reg_rtx (SImode);
3640}")
8ef30996 3641
e7d7b3dc 3642(define_insn "negdi2_internal"
8ef30996
MM
3643 [(set (match_operand:DI 0 "register_operand" "=d")
3644 (neg:DI (match_operand:DI 1 "register_operand" "d")))
3645 (clobber (match_operand:SI 2 "register_operand" "=d"))]
2bcb2ab3 3646 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
3647 "*
3648{
3649 operands[3] = const0_rtx;
3650 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3651}"
3652 [(set_attr "type" "darith")
3653 (set_attr "mode" "DI")
0ff83799 3654 (set_attr "length" "16")])
8ef30996 3655
bb621ad7
JW
3656(define_insn "negdi2_internal_2"
3657 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 3658 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2bcb2ab3 3659 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3660 "*
3661{
3662 operands[2] = const0_rtx;
3663 return \"dsubu\\t%0,%z2,%1\";
3664}"
3665 [(set_attr "type" "arith")
0ff83799 3666 (set_attr "mode" "DI")])
bb621ad7 3667
8ef30996
MM
3668(define_insn "negdf2"
3669 [(set (match_operand:DF 0 "register_operand" "=f")
3670 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
46299de9 3671 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
3672 "neg.d\\t%0,%1"
3673 [(set_attr "type" "fneg")
0ff83799 3674 (set_attr "mode" "DF")])
8ef30996
MM
3675
3676(define_insn "negsf2"
3677 [(set (match_operand:SF 0 "register_operand" "=f")
3678 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3679 "TARGET_HARD_FLOAT"
3680 "neg.s\\t%0,%1"
3681 [(set_attr "type" "fneg")
0ff83799 3682 (set_attr "mode" "SF")])
8ef30996
MM
3683
3684(define_insn "one_cmplsi2"
3685 [(set (match_operand:SI 0 "register_operand" "=d")
3686 (not:SI (match_operand:SI 1 "register_operand" "d")))]
3687 ""
3688 "*
3689{
2bcb2ab3
GK
3690 if (TARGET_MIPS16)
3691 return \"not\\t%0,%1\";
8ef30996
MM
3692 operands[2] = const0_rtx;
3693 return \"nor\\t%0,%z2,%1\";
3694}"
3695 [(set_attr "type" "arith")
0ff83799 3696 (set_attr "mode" "SI")])
8ef30996
MM
3697
3698(define_insn "one_cmpldi2"
3699 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
3700 (not:DI (match_operand:DI 1 "register_operand" "d")))]
3701 "TARGET_64BIT"
8ef30996
MM
3702 "*
3703{
2bcb2ab3 3704 if (TARGET_MIPS16)
cafe096b
EC
3705 return \"not\\t%0,%1\";
3706 return \"nor\\t%0,%.,%1\";
8ef30996
MM
3707}"
3708 [(set_attr "type" "darith")
cafe096b 3709 (set_attr "mode" "DI")])
8ef30996
MM
3710\f
3711;;
3712;; ....................
3713;;
3714;; LOGICAL
3715;;
3716;; ....................
3717;;
3718
2bcb2ab3
GK
3719;; Many of these instructions uses trivial define_expands, because we
3720;; want to use a different set of constraints when TARGET_MIPS16.
3721
3722(define_expand "andsi3"
65437fe8 3723 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
3724 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3725 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8 3726 ""
2bcb2ab3
GK
3727 "
3728{
3729 if (TARGET_MIPS16)
1bfbbbcf
AO
3730 {
3731 operands[1] = force_reg (SImode, operands[1]);
3732 operands[2] = force_reg (SImode, operands[2]);
3733 }
2bcb2ab3
GK
3734}")
3735
3736(define_insn ""
3737 [(set (match_operand:SI 0 "register_operand" "=d,d")
3738 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3739 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3740 "!TARGET_MIPS16"
65437fe8
MM
3741 "@
3742 and\\t%0,%1,%2
3743 andi\\t%0,%1,%x2"
3744 [(set_attr "type" "arith")
0ff83799 3745 (set_attr "mode" "SI")])
65437fe8 3746
2bcb2ab3
GK
3747(define_insn ""
3748 [(set (match_operand:SI 0 "register_operand" "=d")
3749 (and:SI (match_operand:SI 1 "register_operand" "%0")
3750 (match_operand:SI 2 "register_operand" "d")))]
3751 "TARGET_MIPS16"
3752 "and\\t%0,%2"
3753 [(set_attr "type" "arith")
0ff83799 3754 (set_attr "mode" "SI")])
2bcb2ab3
GK
3755
3756(define_expand "anddi3"
cafe096b
EC
3757 [(set (match_operand:DI 0 "register_operand" "")
3758 (and:DI (match_operand:DI 1 "register_operand" "")
3759 (match_operand:DI 2 "uns_arith_operand" "")))]
3760 "TARGET_64BIT"
2bcb2ab3
GK
3761 "
3762{
3763 if (TARGET_MIPS16)
1bfbbbcf
AO
3764 {
3765 operands[1] = force_reg (DImode, operands[1]);
3766 operands[2] = force_reg (DImode, operands[2]);
3767 }
2bcb2ab3
GK
3768}")
3769
3770(define_insn ""
bb621ad7 3771 [(set (match_operand:DI 0 "register_operand" "=d,d")
cafe096b
EC
3772 (and:DI (match_operand:DI 1 "register_operand" "d,d")
3773 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 3774 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3775 "@
3776 and\\t%0,%1,%2
3777 andi\\t%0,%1,%x2"
cafe096b
EC
3778 [(set_attr "type" "darith")
3779 (set_attr "mode" "DI")])
3780
3781(define_insn ""
3782 [(set (match_operand:DI 0 "register_operand" "=d")
3783 (and:DI (match_operand:DI 1 "register_operand" "0")
3784 (match_operand:DI 2 "register_operand" "d")))]
3785 "TARGET_64BIT && TARGET_MIPS16"
3786 "and\\t%0,%2"
3787 [(set_attr "type" "darith")
0ff83799 3788 (set_attr "mode" "DI")])
bb621ad7 3789
2bcb2ab3 3790(define_expand "iorsi3"
65437fe8 3791 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
3792 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3793 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8 3794 ""
2bcb2ab3
GK
3795 "
3796{
3797 if (TARGET_MIPS16)
1bfbbbcf
AO
3798 {
3799 operands[1] = force_reg (SImode, operands[1]);
3800 operands[2] = force_reg (SImode, operands[2]);
3801 }
2bcb2ab3
GK
3802}")
3803
3804(define_insn ""
3805 [(set (match_operand:SI 0 "register_operand" "=d,d")
3806 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3807 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3808 "!TARGET_MIPS16"
65437fe8
MM
3809 "@
3810 or\\t%0,%1,%2
3811 ori\\t%0,%1,%x2"
3812 [(set_attr "type" "arith")
0ff83799 3813 (set_attr "mode" "SI")])
65437fe8 3814
2bcb2ab3
GK
3815(define_insn ""
3816 [(set (match_operand:SI 0 "register_operand" "=d")
3817 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3818 (match_operand:SI 2 "register_operand" "d")))]
3819 "TARGET_MIPS16"
3820 "or\\t%0,%2"
3821 [(set_attr "type" "arith")
0ff83799 3822 (set_attr "mode" "SI")])
2bcb2ab3 3823
2bcb2ab3 3824(define_expand "iordi3"
cafe096b
EC
3825 [(set (match_operand:DI 0 "register_operand" "")
3826 (ior:DI (match_operand:DI 1 "register_operand" "")
3827 (match_operand:DI 2 "uns_arith_operand" "")))]
3828 "TARGET_64BIT"
3829 "
3830{
3831 if (TARGET_MIPS16)
3832 {
3833 operands[1] = force_reg (DImode, operands[1]);
3834 operands[2] = force_reg (DImode, operands[2]);
3835 }
3836}")
2bcb2ab3
GK
3837
3838(define_insn ""
cafe096b
EC
3839 [(set (match_operand:DI 0 "register_operand" "=d,d")
3840 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
3841 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3842 "TARGET_64BIT && !TARGET_MIPS16"
3843 "@
3844 or\t%0,%1,%2
3845 ori\t%0,%1,%x2"
8ef30996 3846 [(set_attr "type" "darith")
cafe096b 3847 (set_attr "mode" "DI")])
8ef30996 3848
2bcb2ab3
GK
3849(define_insn ""
3850 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
3851 (ior:DI (match_operand:DI 1 "register_operand" "0")
3852 (match_operand:DI 2 "register_operand" "d")))]
3853 "TARGET_64BIT && TARGET_MIPS16"
3854 "or\t%0,%2"
2bcb2ab3 3855 [(set_attr "type" "darith")
cafe096b 3856 (set_attr "mode" "DI")])
8ef30996 3857
2bcb2ab3 3858(define_expand "xorsi3"
65437fe8 3859 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
3860 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3861 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8 3862 ""
2bcb2ab3
GK
3863 "")
3864
3865(define_insn ""
3866 [(set (match_operand:SI 0 "register_operand" "=d,d")
3867 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3868 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3869 "!TARGET_MIPS16"
65437fe8
MM
3870 "@
3871 xor\\t%0,%1,%2
3872 xori\\t%0,%1,%x2"
3873 [(set_attr "type" "arith")
0ff83799 3874 (set_attr "mode" "SI")])
65437fe8 3875
2bcb2ab3
GK
3876(define_insn ""
3877 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3878 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3879 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3880 "TARGET_MIPS16"
3881 "@
3882 xor\\t%0,%2
3883 cmpi\\t%1,%2
3884 cmp\\t%1,%2"
3885 [(set_attr "type" "arith")
3886 (set_attr "mode" "SI")
3887 (set_attr_alternative "length"
0ff83799 3888 [(const_int 4)
2bcb2ab3 3889 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
3890 (const_int 4)
3891 (const_int 8))
3892 (const_int 4)])])
2bcb2ab3 3893
2bcb2ab3 3894(define_expand "xordi3"
cafe096b
EC
3895 [(set (match_operand:DI 0 "register_operand" "")
3896 (xor:DI (match_operand:DI 1 "register_operand" "")
3897 (match_operand:DI 2 "uns_arith_operand" "")))]
3898 "TARGET_64BIT"
3899 "
bb621ad7 3900{
cafe096b
EC
3901 if (TARGET_MIPS16)
3902 {
3903 operands[1] = force_reg (DImode, operands[1]);
3904 operands[2] = force_reg (DImode, operands[2]);
3905 }
3906}")
8ef30996 3907
2bcb2ab3 3908(define_insn ""
cafe096b
EC
3909 [(set (match_operand:DI 0 "register_operand" "=d,d")
3910 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
3911 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3912 "TARGET_64BIT && !TARGET_MIPS16"
3913 "@
3914 xor\t%0,%1,%2
3915 xori\t%0,%1,%x2"
2bcb2ab3 3916 [(set_attr "type" "darith")
cafe096b 3917 (set_attr "mode" "DI")])
2bcb2ab3
GK
3918
3919(define_insn ""
3920 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
cafe096b
EC
3921 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
3922 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
2bcb2ab3
GK
3923 "TARGET_64BIT && TARGET_MIPS16"
3924 "@
3925 xor\\t%0,%2
3926 cmpi\\t%1,%2
3927 cmp\\t%1,%2"
3928 [(set_attr "type" "arith")
3929 (set_attr "mode" "DI")
3930 (set_attr_alternative "length"
0ff83799 3931 [(const_int 4)
2bcb2ab3 3932 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
3933 (const_int 4)
3934 (const_int 8))
3935 (const_int 4)])])
2bcb2ab3 3936
77a8368e
JW
3937(define_insn "*norsi3"
3938 [(set (match_operand:SI 0 "register_operand" "=d")
3939 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3940 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2bcb2ab3 3941 "!TARGET_MIPS16"
77a8368e
JW
3942 "nor\\t%0,%z1,%z2"
3943 [(set_attr "type" "arith")
0ff83799 3944 (set_attr "mode" "SI")])
77a8368e
JW
3945
3946(define_insn "*nordi3"
3947 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
3948 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
3949 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
3950 "TARGET_64BIT && !TARGET_MIPS16"
3951 "nor\\t%0,%z1,%z2"
77a8368e 3952 [(set_attr "type" "darith")
cafe096b 3953 (set_attr "mode" "DI")])
8ef30996
MM
3954\f
3955;;
3956;; ....................
3957;;
3958;; TRUNCATION
3959;;
3960;; ....................
3961
cafe096b
EC
3962
3963
8ef30996
MM
3964(define_insn "truncdfsf2"
3965 [(set (match_operand:SF 0 "register_operand" "=f")
3966 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
46299de9 3967 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
3968 "cvt.s.d\\t%0,%1"
3969 [(set_attr "type" "fcvt")
0ff83799 3970 (set_attr "mode" "SF")])
8ef30996 3971
cafe096b
EC
3972;; Integer truncation patterns. Truncating SImode values to smaller
3973;; modes is a no-op, as it is for most other GCC ports. Truncating
3974;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3975;; need to make sure that the lower 32 bits are properly sign-extended
3976;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
3977;; smaller than SImode is equivalent to two separate truncations:
3978;;
3979;; A B
3980;; DI ---> HI == DI ---> SI ---> HI
3981;; DI ---> QI == DI ---> SI ---> QI
3982;;
3983;; Step A needs a real instruction but step B does not.
3984
8894cf34 3985(define_insn "truncdisi2"
cafe096b
EC
3986 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3987 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
bb621ad7 3988 "TARGET_64BIT"
cafe096b
EC
3989 "@
3990 sll\t%0,%1,0
3991 sw\t%1,%0"
3992 [(set_attr "type" "darith")
3993 (set_attr "mode" "SI")
3994 (set_attr "extended_mips16" "yes,*")])
bb621ad7 3995
8894cf34 3996(define_insn "truncdihi2"
cafe096b
EC
3997 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
3998 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
00bb4b62 3999 "TARGET_64BIT"
cafe096b
EC
4000 "@
4001 sll\t%0,%1,0
4002 sh\t%1,%0"
4003 [(set_attr "type" "darith")
4004 (set_attr "mode" "SI")
4005 (set_attr "extended_mips16" "yes,*")])
4006
8894cf34 4007(define_insn "truncdiqi2"
cafe096b
EC
4008 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
4009 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
00bb4b62 4010 "TARGET_64BIT"
cafe096b
EC
4011 "@
4012 sll\t%0,%1,0
4013 sb\t%1,%0"
4014 [(set_attr "type" "darith")
4015 (set_attr "mode" "SI")
4016 (set_attr "extended_mips16" "yes,*")])
a67f7692
JW
4017
4018;; Combiner patterns to optimize shift/truncate combinations.
cafe096b 4019
a67f7692
JW
4020(define_insn ""
4021 [(set (match_operand:SI 0 "register_operand" "=d")
cafe096b
EC
4022 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4023 (match_operand:DI 2 "small_int" "I"))))]
4024 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
4025 "dsra\\t%0,%1,%2"
4026 [(set_attr "type" "darith")
4027 (set_attr "mode" "SI")])
7a38df19 4028
a67f7692
JW
4029(define_insn ""
4030 [(set (match_operand:SI 0 "register_operand" "=d")
cafe096b
EC
4031 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4032 (const_int 32))))]
2bcb2ab3 4033 "TARGET_64BIT && !TARGET_MIPS16"
cafe096b
EC
4034 "dsra\\t%0,%1,32"
4035 [(set_attr "type" "darith")
4036 (set_attr "mode" "SI")])
a67f7692 4037
a67f7692 4038
cafe096b
EC
4039;; Combiner patterns for truncate/sign_extend combinations. They use
4040;; the shift/truncate patterns above.
4041
4042(define_insn_and_split ""
a67f7692 4043 [(set (match_operand:SI 0 "register_operand" "=d")
cafe096b
EC
4044 (sign_extend:SI
4045 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
4046 "TARGET_64BIT && !TARGET_MIPS16"
4047 "#"
4048 "&& reload_completed"
4049 [(set (match_dup 2)
4050 (ashift:DI (match_dup 1)
4051 (const_int 48)))
4052 (set (match_dup 0)
4053 (truncate:SI (ashiftrt:DI (match_dup 2)
4054 (const_int 48))))]
4055 { operands[2] = gen_lowpart (DImode, operands[0]); })
4056
4057(define_insn_and_split ""
4058 [(set (match_operand:SI 0 "register_operand" "=d")
4059 (sign_extend:SI
4060 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
4061 "TARGET_64BIT && !TARGET_MIPS16"
4062 "#"
4063 "&& reload_completed"
4064 [(set (match_dup 2)
4065 (ashift:DI (match_dup 1)
4066 (const_int 56)))
4067 (set (match_dup 0)
4068 (truncate:SI (ashiftrt:DI (match_dup 2)
4069 (const_int 56))))]
4070 { operands[2] = gen_lowpart (DImode, operands[0]); })
a67f7692 4071
99f762bf
JW
4072
4073;; Combiner patterns to optimize truncate/zero_extend combinations.
4074
4075(define_insn ""
4076 [(set (match_operand:SI 0 "register_operand" "=d")
cafe096b
EC
4077 (zero_extend:SI (truncate:HI
4078 (match_operand:DI 1 "register_operand" "d"))))]
2bcb2ab3 4079 "TARGET_64BIT && !TARGET_MIPS16"
99f762bf 4080 "andi\\t%0,%1,0xffff"
cafe096b
EC
4081 [(set_attr "type" "darith")
4082 (set_attr "mode" "SI")])
99f762bf
JW
4083
4084(define_insn ""
4085 [(set (match_operand:SI 0 "register_operand" "=d")
cafe096b
EC
4086 (zero_extend:SI (truncate:QI
4087 (match_operand:DI 1 "register_operand" "d"))))]
2bcb2ab3 4088 "TARGET_64BIT && !TARGET_MIPS16"
99f762bf 4089 "andi\\t%0,%1,0xff"
cafe096b
EC
4090 [(set_attr "type" "darith")
4091 (set_attr "mode" "SI")])
99f762bf
JW
4092
4093(define_insn ""
4094 [(set (match_operand:HI 0 "register_operand" "=d")
cafe096b
EC
4095 (zero_extend:HI (truncate:QI
4096 (match_operand:DI 1 "register_operand" "d"))))]
2bcb2ab3 4097 "TARGET_64BIT && !TARGET_MIPS16"
99f762bf 4098 "andi\\t%0,%1,0xff"
cafe096b
EC
4099 [(set_attr "type" "darith")
4100 (set_attr "mode" "HI")])
4101
8ef30996
MM
4102\f
4103;;
4104;; ....................
4105;;
4106;; ZERO EXTENSION
4107;;
4108;; ....................
4109
4110;; Extension insns.
abdf3eea 4111;; Those for integer source operand are ordered widest source type first.
8ef30996 4112
cafe096b
EC
4113(define_insn_and_split "zero_extendsidi2"
4114 [(set (match_operand:DI 0 "register_operand" "=d")
4115 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
bb621ad7 4116 "TARGET_64BIT"
cafe096b
EC
4117 "#"
4118 "&& reload_completed"
4119 [(set (match_dup 0)
4120 (ashift:DI (match_dup 1) (const_int 32)))
4121 (set (match_dup 0)
4122 (lshiftrt:DI (match_dup 0) (const_int 32)))]
4123 "operands[1] = gen_lowpart (DImode, operands[1]);"
4124 [(set_attr "type" "arith")
4125 (set_attr "mode" "DI")])
bb621ad7 4126
cafe096b
EC
4127(define_insn "*zero_extendsidi2_mem"
4128 [(set (match_operand:DI 0 "register_operand" "=d")
4129 (zero_extend:DI (match_operand:SI 1 "memory_operand" "m")))]
b5031ab7 4130 "TARGET_64BIT && !TARGET_MIPS16"
cafe096b
EC
4131 "lwu\t%0,%1"
4132 [(set_attr "type" "load")
4133 (set_attr "mode" "DI")])
bb621ad7 4134
2bcb2ab3
GK
4135(define_expand "zero_extendhisi2"
4136 [(set (match_operand:SI 0 "register_operand" "")
cafe096b 4137 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2bcb2ab3
GK
4138 ""
4139 "
4140{
4141 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4142 {
4143 rtx op = gen_lowpart (SImode, operands[1]);
4144 rtx temp = force_reg (SImode, GEN_INT (0xffff));
4145
4146 emit_insn (gen_andsi3 (operands[0], op, temp));
4147 DONE;
4148 }
4149}")
4150
4151(define_insn ""
cafe096b
EC
4152 [(set (match_operand:SI 0 "register_operand" "=d,d")
4153 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2bcb2ab3 4154 "!TARGET_MIPS16"
cafe096b
EC
4155 "@
4156 andi\t%0,%1,0xffff
4157 lhu\t%0,%1"
4158 [(set_attr "type" "arith,load")
4159 (set_attr "mode" "SI")
4160 (set_attr "length" "4,*")])
8ef30996 4161
2bcb2ab3 4162(define_insn ""
cafe096b
EC
4163 [(set (match_operand:SI 0 "register_operand" "=d")
4164 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2bcb2ab3 4165 "TARGET_MIPS16"
cafe096b
EC
4166 "lhu\t%0,%1"
4167 [(set_attr "type" "load")
4168 (set_attr "mode" "SI")])
2bcb2ab3
GK
4169
4170(define_expand "zero_extendhidi2"
4171 [(set (match_operand:DI 0 "register_operand" "")
cafe096b 4172 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
2bcb2ab3
GK
4173 "TARGET_64BIT"
4174 "
4175{
4176 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4177 {
4178 rtx op = gen_lowpart (DImode, operands[1]);
4179 rtx temp = force_reg (DImode, GEN_INT (0xffff));
4180
4181 emit_insn (gen_anddi3 (operands[0], op, temp));
4182 DONE;
4183 }
4184}")
4185
4186(define_insn ""
cafe096b
EC
4187 [(set (match_operand:DI 0 "register_operand" "=d,d")
4188 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2bcb2ab3 4189 "TARGET_64BIT && !TARGET_MIPS16"
cafe096b
EC
4190 "@
4191 andi\t%0,%1,0xffff
4192 lhu\t%0,%1"
4193 [(set_attr "type" "arith,load")
4194 (set_attr "mode" "DI")
4195 (set_attr "length" "4,*")])
bb621ad7 4196
2bcb2ab3 4197(define_insn ""
cafe096b
EC
4198 [(set (match_operand:DI 0 "register_operand" "=d")
4199 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2bcb2ab3 4200 "TARGET_64BIT && TARGET_MIPS16"
cafe096b
EC
4201 "lhu\t%0,%1"
4202 [(set_attr "type" "load")
4203 (set_attr "mode" "DI")])
2bcb2ab3
GK
4204
4205(define_expand "zero_extendqihi2"
4206 [(set (match_operand:HI 0 "register_operand" "")
4207 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
4208 ""
4209 "
4210{
4211 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4212 {
4213 rtx op0 = gen_lowpart (SImode, operands[0]);
4214 rtx op1 = gen_lowpart (SImode, operands[1]);
4215 rtx temp = force_reg (SImode, GEN_INT (0xff));
4216
4217 emit_insn (gen_andsi3 (op0, op1, temp));
4218 DONE;
4219 }
4220}")
4221
2bcb2ab3
GK
4222(define_insn ""
4223 [(set (match_operand:HI 0 "register_operand" "=d,d")
cafe096b
EC
4224 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
4225 "!TARGET_MIPS16"
4226 "@
4227 andi\t%0,%1,0x00ff
4228 lbu\t%0,%1"
4229 [(set_attr "type" "arith,load")
4230 (set_attr "mode" "HI")
4231 (set_attr "length" "4,*")])
4232
4233(define_insn ""
4234 [(set (match_operand:HI 0 "register_operand" "=d")
4235 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2bcb2ab3 4236 "TARGET_MIPS16"
cafe096b
EC
4237 "lbu\t%0,%1"
4238 [(set_attr "type" "load")
4239 (set_attr "mode" "HI")])
2bcb2ab3
GK
4240
4241(define_expand "zero_extendqisi2"
4242 [(set (match_operand:SI 0 "register_operand" "")
4243 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4244 ""
4245 "
4246{
4247 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4248 {
4249 rtx op = gen_lowpart (SImode, operands[1]);
4250 rtx temp = force_reg (SImode, GEN_INT (0xff));
4251
4252 emit_insn (gen_andsi3 (operands[0], op, temp));
4253 DONE;
4254 }
4255}")
4256
4257(define_insn ""
cafe096b
EC
4258 [(set (match_operand:SI 0 "register_operand" "=d,d")
4259 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2bcb2ab3 4260 "!TARGET_MIPS16"
cafe096b
EC
4261 "@
4262 andi\t%0,%1,0x00ff
4263 lbu\t%0,%1"
4264 [(set_attr "type" "arith,load")
4265 (set_attr "mode" "SI")
4266 (set_attr "length" "4,*")])
8ef30996 4267
2bcb2ab3 4268(define_insn ""
cafe096b
EC
4269 [(set (match_operand:SI 0 "register_operand" "=d")
4270 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2bcb2ab3 4271 "TARGET_MIPS16"
cafe096b
EC
4272 "lbu\t%0,%1"
4273 [(set_attr "type" "load")
4274 (set_attr "mode" "SI")])
2bcb2ab3
GK
4275
4276(define_expand "zero_extendqidi2"
4277 [(set (match_operand:DI 0 "register_operand" "")
4278 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4279 "TARGET_64BIT"
4280 "
4281{
4282 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
4283 {
4284 rtx op = gen_lowpart (DImode, operands[1]);
4285 rtx temp = force_reg (DImode, GEN_INT (0xff));
4286
4287 emit_insn (gen_anddi3 (operands[0], op, temp));
4288 DONE;
4289 }
4290}")
4291
4292(define_insn ""
cafe096b
EC
4293 [(set (match_operand:DI 0 "register_operand" "=d,d")
4294 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2bcb2ab3 4295 "TARGET_64BIT && !TARGET_MIPS16"
cafe096b
EC
4296 "@
4297 andi\t%0,%1,0x00ff
4298 lbu\t%0,%1"
4299 [(set_attr "type" "arith,load")
4300 (set_attr "mode" "DI")
4301 (set_attr "length" "4,*")])
bb621ad7 4302
3cce8bc6
JW
4303;; These can be created when a paradoxical subreg operand with an implicit
4304;; sign_extend operator is reloaded. Because of the subreg, this is really
4305;; a zero extend.
4306;; ??? It might be possible to eliminate the need for these patterns by adding
4307;; more support to reload for implicit sign_extend operators.
4308(define_insn "*paradoxical_extendhidi2"
cafe096b 4309 [(set (match_operand:DI 0 "register_operand" "=d")
3cce8bc6 4310 (sign_extend:DI
cafe096b 4311 (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)))]
3cce8bc6
JW
4312 "TARGET_64BIT"
4313 "*
4314{
4315 return mips_move_1word (operands, insn, TRUE);
4316}"
cafe096b
EC
4317 [(set_attr "type" "load")
4318 (set_attr "mode" "DI")])
3cce8bc6 4319
2bcb2ab3 4320(define_insn ""
cafe096b
EC
4321 [(set (match_operand:DI 0 "register_operand" "=d")
4322 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2bcb2ab3 4323 "TARGET_64BIT && TARGET_MIPS16"
cafe096b
EC
4324 "lbu\t%0,%1"
4325 [(set_attr "type" "load")
4326 (set_attr "mode" "DI")])
8ef30996
MM
4327\f
4328;;
4329;; ....................
4330;;
4331;; SIGN EXTENSION
4332;;
4333;; ....................
4334
4335;; Extension insns.
abdf3eea 4336;; Those for integer source operand are ordered widest source type first.
8ef30996 4337
8214bf98
RS
4338(define_expand "extendsidi2"
4339 [(set (match_operand:DI 0 "register_operand" "")
cafe096b 4340 (sign_extend:DI (match_operand:SI 1 "move_operand" "")))]
abdf3eea 4341 "TARGET_64BIT"
cafe096b
EC
4342 "
4343{
4344 if (symbolic_operand (operands[1], SImode))
4345 {
4346 emit_move_insn (operands[0], convert_memory_address (DImode, operands[1]));
4347 DONE;
4348 }
4349
4350}")
4351
4352(define_insn "*extendsidi2"
4353 [(set (match_operand:DI 0 "register_operand" "=d,d")
4354 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
4355 "TARGET_64BIT"
4356 "@
4357 sll\t%0,%1,0
4358 lw\t%0,%1"
4359 [(set_attr "type" "arith,load")
4360 (set_attr "mode" "DI")
4361 (set_attr "extended_mips16" "yes,*")])
bb621ad7 4362
8ef30996
MM
4363;; These patterns originally accepted general_operands, however, slightly
4364;; better code is generated by only accepting register_operands, and then
4365;; letting combine generate the lh and lb insns.
4366
cafe096b
EC
4367;; These expanders originally put values in registers first. We split
4368;; all non-mem patterns after reload.
4369
bb621ad7
JW
4370(define_expand "extendhidi2"
4371 [(set (match_operand:DI 0 "register_operand" "")
cafe096b 4372 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
bb621ad7 4373 "TARGET_64BIT"
cafe096b 4374 "")
bb621ad7 4375
cafe096b
EC
4376(define_insn "*extendhidi2"
4377 [(set (match_operand:DI 0 "register_operand" "=d")
4378 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
4379 "TARGET_64BIT"
4380 "#")
bb621ad7 4381
cafe096b
EC
4382(define_split
4383 [(set (match_operand:DI 0 "register_operand" "")
4384 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4385 "TARGET_64BIT && reload_completed"
4386 [(set (match_dup 0)
4387 (ashift:DI (match_dup 1) (const_int 48)))
4388 (set (match_dup 0)
4389 (ashiftrt:DI (match_dup 0) (const_int 48)))]
4390 "operands[1] = gen_lowpart (DImode, operands[1]);")
bb621ad7 4391
cafe096b
EC
4392(define_insn "*extendhidi2_mem"
4393 [(set (match_operand:DI 0 "register_operand" "=d")
4394 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
bb621ad7 4395 "TARGET_64BIT"
cafe096b
EC
4396 "lh\t%0,%1"
4397 [(set_attr "type" "load")
4398 (set_attr "mode" "DI")])
bb621ad7 4399
8ef30996
MM
4400(define_expand "extendhisi2"
4401 [(set (match_operand:SI 0 "register_operand" "")
cafe096b 4402 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
8ef30996
MM
4403 ""
4404 "
cafe096b
EC
4405 if (ISA_HAS_SEB_SEH)
4406 {
4407 emit_insn (gen_extendhisi2_hw (operands[0],
4408 force_reg (HImode, operands[1])));
4409 DONE;
4410 }
4411")
2d2a50c3 4412
cafe096b
EC
4413(define_insn "*extendhisi2"
4414 [(set (match_operand:SI 0 "register_operand" "=d")
4415 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
4416 ""
4417 "#")
8ef30996 4418
cafe096b
EC
4419(define_split
4420 [(set (match_operand:SI 0 "register_operand" "")
4421 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4422 "reload_completed"
4423 [(set (match_dup 0)
4424 (ashift:SI (match_dup 1) (const_int 16)))
4425 (set (match_dup 0)
4426 (ashiftrt:SI (match_dup 0) (const_int 16)))]
4427 "operands[1] = gen_lowpart (SImode, operands[1]);")
8ef30996 4428
cafe096b
EC
4429(define_insn "extendhisi2_mem"
4430 [(set (match_operand:SI 0 "register_operand" "=d")
4431 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4432 ""
4433 "lh\t%0,%1"
4434 [(set_attr "type" "load")
4435 (set_attr "mode" "SI")])
8ef30996 4436
cafe096b 4437(define_insn "extendhisi2_hw"
2d2a50c3 4438 [(set (match_operand:SI 0 "register_operand" "=r")
cafe096b
EC
4439 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4440 "ISA_HAS_SEB_SEH"
2d2a50c3
CD
4441 "seh\\t%0,%1"
4442 [(set_attr "type" "arith")
4443 (set_attr "mode" "SI")])
4444
8ef30996
MM
4445(define_expand "extendqihi2"
4446 [(set (match_operand:HI 0 "register_operand" "")
cafe096b 4447 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
8ef30996 4448 ""
cafe096b 4449 "")
8ef30996 4450
cafe096b
EC
4451(define_insn "*extendqihi2"
4452 [(set (match_operand:HI 0 "register_operand" "=d")
4453 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
4454 ""
4455 "#")
8ef30996 4456
cafe096b
EC
4457(define_split
4458 [(set (match_operand:HI 0 "register_operand" "")
4459 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4460 "reload_completed"
4461 [(set (match_dup 0)
4462 (ashift:SI (match_dup 1) (const_int 24)))
4463 (set (match_dup 0)
4464 (ashiftrt:SI (match_dup 0) (const_int 24)))]
4465 "operands[0] = gen_lowpart (SImode, operands[0]);
4466 operands[1] = gen_lowpart (SImode, operands[1]);")
8ef30996 4467
cafe096b
EC
4468(define_insn "*extendqihi2_internal_mem"
4469 [(set (match_operand:HI 0 "register_operand" "=d")
4470 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
8ef30996 4471 ""
cafe096b
EC
4472 "lb\t%0,%1"
4473 [(set_attr "type" "load")
4474 (set_attr "mode" "SI")])
8ef30996
MM
4475
4476
4477(define_expand "extendqisi2"
4478 [(set (match_operand:SI 0 "register_operand" "")
cafe096b 4479 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
8ef30996
MM
4480 ""
4481 "
cafe096b
EC
4482 if (ISA_HAS_SEB_SEH)
4483 {
4484 emit_insn (gen_extendqisi2_hw (operands[0],
4485 force_reg (QImode, operands[1])));
4486 DONE;
4487 }
4488")
8ef30996 4489
cafe096b
EC
4490(define_insn "*extendqisi2"
4491 [(set (match_operand:SI 0 "register_operand" "=d")
4492 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
4493 ""
4494 "#")
8ef30996 4495
cafe096b
EC
4496(define_split
4497 [(set (match_operand:SI 0 "register_operand" "")
4498 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4499 "reload_completed"
4500 [(set (match_dup 0)
4501 (ashift:SI (match_dup 1) (const_int 24)))
4502 (set (match_dup 0)
4503 (ashiftrt:SI (match_dup 0) (const_int 24)))]
4504 "operands[1] = gen_lowpart (SImode, operands[1]);")
4505
4506(define_insn "*extendqisi2_mem"
4507 [(set (match_operand:SI 0 "register_operand" "=d")
4508 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4509 ""
4510 "lb\t%0,%1"
4511 [(set_attr "type" "load")
4512 (set_attr "mode" "SI")])
8ef30996 4513
cafe096b 4514(define_insn "extendqisi2_hw"
2d2a50c3 4515 [(set (match_operand:SI 0 "register_operand" "=r")
cafe096b
EC
4516 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4517 "ISA_HAS_SEB_SEH"
2d2a50c3
CD
4518 "seb\\t%0,%1"
4519 [(set_attr "type" "arith")
4520 (set_attr "mode" "SI")])
4521
bb621ad7
JW
4522(define_expand "extendqidi2"
4523 [(set (match_operand:DI 0 "register_operand" "")
cafe096b 4524 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
bb621ad7 4525 "TARGET_64BIT"
cafe096b 4526 "")
bb621ad7 4527
cafe096b
EC
4528(define_insn "*extendqidi2"
4529 [(set (match_operand:DI 0 "register_operand" "=d")
4530 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
4531 "TARGET_64BIT"
4532 "#")
bb621ad7 4533
cafe096b
EC
4534(define_split
4535 [(set (match_operand:DI 0 "register_operand" "")
4536 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4537 "TARGET_64BIT && reload_completed"
4538 [(set (match_dup 0)
4539 (ashift:DI (match_dup 1) (const_int 56)))
4540 (set (match_dup 0)
4541 (ashiftrt:DI (match_dup 0) (const_int 56)))]
4542 "operands[1] = gen_lowpart (DImode, operands[1]);")
bb621ad7 4543
cafe096b
EC
4544(define_insn "*extendqidi2_mem"
4545 [(set (match_operand:DI 0 "register_operand" "=d")
4546 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
bb621ad7 4547 "TARGET_64BIT"
cafe096b
EC
4548 "lb\t%0,%1"
4549 [(set_attr "type" "load")
4550 (set_attr "mode" "DI")])
8ef30996
MM
4551
4552(define_insn "extendsfdf2"
4553 [(set (match_operand:DF 0 "register_operand" "=f")
4554 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
46299de9 4555 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4556 "cvt.d.s\\t%0,%1"
4557 [(set_attr "type" "fcvt")
0ff83799 4558 (set_attr "mode" "DF")])
8ef30996
MM
4559
4560\f
4561
4562;;
4563;; ....................
4564;;
4565;; CONVERSIONS
4566;;
4567;; ....................
4568
8214bf98
RS
4569(define_expand "fix_truncdfsi2"
4570 [(set (match_operand:SI 0 "register_operand" "=f")
4571 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
46299de9 4572 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996 4573{
8214bf98
RS
4574 if (!ISA_HAS_TRUNC_W)
4575 {
4576 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
4577 DONE;
4578 }
4579})
8ef30996 4580
8214bf98
RS
4581(define_insn "fix_truncdfsi2_insn"
4582 [(set (match_operand:SI 0 "register_operand" "=f")
4583 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
4584 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
4585 "trunc.w.d %0,%1"
92b4cee1
MM
4586 [(set_attr "type" "fcvt")
4587 (set_attr "mode" "DF")
8214bf98
RS
4588 (set_attr "length" "4")])
4589
4590(define_insn "fix_truncdfsi2_macro"
4591 [(set (match_operand:SI 0 "register_operand" "=f")
4592 (fix:SI (match_operand:DF 1 "register_operand" "f")))
4593 (clobber (match_scratch:DF 2 "=d"))]
4594 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
4595 "trunc.w.d %0,%1,%2"
4596 [(set_attr "type" "fcvt")
4597 (set_attr "mode" "DF")
4598 (set_attr "length" "36")])
8ef30996 4599
8214bf98
RS
4600(define_expand "fix_truncsfsi2"
4601 [(set (match_operand:SI 0 "register_operand" "=f")
4602 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
8ef30996 4603 "TARGET_HARD_FLOAT"
8ef30996 4604{
8214bf98
RS
4605 if (!ISA_HAS_TRUNC_W)
4606 {
4607 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
4608 DONE;
4609 }
4610})
8ef30996 4611
8214bf98
RS
4612(define_insn "fix_truncsfsi2_insn"
4613 [(set (match_operand:SI 0 "register_operand" "=f")
4614 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
4615 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
4616 "trunc.w.s %0,%1"
92b4cee1 4617 [(set_attr "type" "fcvt")
8214bf98
RS
4618 (set_attr "mode" "DF")
4619 (set_attr "length" "4")])
4620
4621(define_insn "fix_truncsfsi2_macro"
4622 [(set (match_operand:SI 0 "register_operand" "=f")
4623 (fix:SI (match_operand:SF 1 "register_operand" "f")))
4624 (clobber (match_scratch:SF 2 "=d"))]
4625 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
4626 "trunc.w.s %0,%1,%2"
4627 [(set_attr "type" "fcvt")
4628 (set_attr "mode" "DF")
4629 (set_attr "length" "36")])
8ef30996 4630
bb621ad7
JW
4631;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4632;;; but not in the chapter that describes the FPU. It is not mentioned at all
4633;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4634
4635;;; Deleting this means that we now need two libgcc2.a libraries. One for
4636;;; the 32 bit calling convention and one for the 64 bit calling convention.
4637
4638;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4639
4640(define_insn "fix_truncdfdi2"
8214bf98
RS
4641 [(set (match_operand:DI 0 "register_operand" "=f")
4642 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
4643 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4644 "trunc.l.d %0,%1"
bb621ad7
JW
4645 [(set_attr "type" "fcvt")
4646 (set_attr "mode" "DF")
8214bf98 4647 (set_attr "length" "4")])
bb621ad7
JW
4648
4649
4650;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4651;;; but not in the chapter that describes the FPU. It is not mentioned at all
4652;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4653(define_insn "fix_truncsfdi2"
8214bf98
RS
4654 [(set (match_operand:DI 0 "register_operand" "=f")
4655 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
4656 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4657 "trunc.l.s %0,%1"
bb621ad7
JW
4658 [(set_attr "type" "fcvt")
4659 (set_attr "mode" "SF")
8214bf98 4660 (set_attr "length" "4")])
bb621ad7
JW
4661
4662
8ef30996 4663(define_insn "floatsidf2"
8214bf98
RS
4664 [(set (match_operand:DF 0 "register_operand" "=f")
4665 (float:DF (match_operand:SI 1 "register_operand" "f")))]
46299de9 4666 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8214bf98 4667 "cvt.d.w\\t%0,%1"
92b4cee1
MM
4668 [(set_attr "type" "fcvt")
4669 (set_attr "mode" "DF")
8214bf98 4670 (set_attr "length" "4")])
8ef30996 4671
c7343333 4672
bb621ad7 4673(define_insn "floatdidf2"
8214bf98
RS
4674 [(set (match_operand:DF 0 "register_operand" "=f")
4675 (float:DF (match_operand:DI 1 "register_operand" "f")))]
4676 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4677 "cvt.d.l\\t%0,%1"
bb621ad7
JW
4678 [(set_attr "type" "fcvt")
4679 (set_attr "mode" "DF")
8214bf98 4680 (set_attr "length" "4")])
bb621ad7
JW
4681
4682
8ef30996 4683(define_insn "floatsisf2"
8214bf98
RS
4684 [(set (match_operand:SF 0 "register_operand" "=f")
4685 (float:SF (match_operand:SI 1 "register_operand" "f")))]
8ef30996 4686 "TARGET_HARD_FLOAT"
8214bf98 4687 "cvt.s.w\\t%0,%1"
92b4cee1
MM
4688 [(set_attr "type" "fcvt")
4689 (set_attr "mode" "SF")
8214bf98 4690 (set_attr "length" "4")])
bbdb5552 4691
8ef30996 4692
bb621ad7 4693(define_insn "floatdisf2"
8214bf98
RS
4694 [(set (match_operand:SF 0 "register_operand" "=f")
4695 (float:SF (match_operand:DI 1 "register_operand" "f")))]
4696 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
4697 "cvt.s.l\\t%0,%1"
bb621ad7
JW
4698 [(set_attr "type" "fcvt")
4699 (set_attr "mode" "SF")
8214bf98 4700 (set_attr "length" "4")])
bb621ad7
JW
4701
4702
8ef30996
MM
4703(define_expand "fixuns_truncdfsi2"
4704 [(set (match_operand:SI 0 "register_operand" "")
4705 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
46299de9 4706 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4707 "
4708{
4709 rtx reg1 = gen_reg_rtx (DFmode);
4710 rtx reg2 = gen_reg_rtx (DFmode);
4711 rtx reg3 = gen_reg_rtx (SImode);
4712 rtx label1 = gen_label_rtx ();
4713 rtx label2 = gen_label_rtx ();
eef709c7
KG
4714 REAL_VALUE_TYPE offset;
4715
eaff3bf8 4716 real_2expN (&offset, 31);
8ef30996
MM
4717
4718 if (reg1) /* turn off complaints about unreached code */
4719 {
5692c7bc 4720 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
8ef30996
MM
4721 do_pending_stack_adjust ();
4722
4723 emit_insn (gen_cmpdf (operands[1], reg1));
4724 emit_jump_insn (gen_bge (label1));
4725
4726 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
c5c76735
JL
4727 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4728 gen_rtx_LABEL_REF (VOIDmode, label2)));
8ef30996
MM
4729 emit_barrier ();
4730
4731 emit_label (label1);
c5c76735 4732 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
024c02b1
AO
4733 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4734 (BITMASK_HIGH, SImode)));
8ef30996
MM
4735
4736 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4737 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4738
4739 emit_label (label2);
4740
4741 /* allow REG_NOTES to be set on last insn (labels don't have enough
4742 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4743 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8ef30996
MM
4744 DONE;
4745 }
4746}")
4747
c7343333 4748
bb621ad7
JW
4749(define_expand "fixuns_truncdfdi2"
4750 [(set (match_operand:DI 0 "register_operand" "")
4751 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
46299de9 4752 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
bb621ad7
JW
4753 "
4754{
4755 rtx reg1 = gen_reg_rtx (DFmode);
4756 rtx reg2 = gen_reg_rtx (DFmode);
4757 rtx reg3 = gen_reg_rtx (DImode);
4758 rtx label1 = gen_label_rtx ();
4759 rtx label2 = gen_label_rtx ();
eef709c7
KG
4760 REAL_VALUE_TYPE offset;
4761
eaff3bf8 4762 real_2expN (&offset, 63);
bb621ad7
JW
4763
4764 if (reg1) /* turn off complaints about unreached code */
4765 {
5692c7bc 4766 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
bb621ad7
JW
4767 do_pending_stack_adjust ();
4768
4769 emit_insn (gen_cmpdf (operands[1], reg1));
4770 emit_jump_insn (gen_bge (label1));
4771
4772 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
c5c76735
JL
4773 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4774 gen_rtx_LABEL_REF (VOIDmode, label2)));
bb621ad7
JW
4775 emit_barrier ();
4776
4777 emit_label (label1);
c5c76735 4778 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3a6ee9f4 4779 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
bb621ad7
JW
4780 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4781
4782 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4783 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4784
4785 emit_label (label2);
4786
4787 /* allow REG_NOTES to be set on last insn (labels don't have enough
4788 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4789 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
bb621ad7
JW
4790 DONE;
4791 }
4792}")
4793
4794
8ef30996
MM
4795(define_expand "fixuns_truncsfsi2"
4796 [(set (match_operand:SI 0 "register_operand" "")
4797 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4798 "TARGET_HARD_FLOAT"
4799 "
4800{
4801 rtx reg1 = gen_reg_rtx (SFmode);
4802 rtx reg2 = gen_reg_rtx (SFmode);
4803 rtx reg3 = gen_reg_rtx (SImode);
4804 rtx label1 = gen_label_rtx ();
4805 rtx label2 = gen_label_rtx ();
eef709c7
KG
4806 REAL_VALUE_TYPE offset;
4807
eaff3bf8 4808 real_2expN (&offset, 31);
8ef30996
MM
4809
4810 if (reg1) /* turn off complaints about unreached code */
4811 {
5692c7bc 4812 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
8ef30996
MM
4813 do_pending_stack_adjust ();
4814
4815 emit_insn (gen_cmpsf (operands[1], reg1));
4816 emit_jump_insn (gen_bge (label1));
4817
4818 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
c5c76735
JL
4819 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4820 gen_rtx_LABEL_REF (VOIDmode, label2)));
8ef30996
MM
4821 emit_barrier ();
4822
4823 emit_label (label1);
c5c76735 4824 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
7cbdf575
AO
4825 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
4826 (BITMASK_HIGH, SImode)));
8ef30996
MM
4827
4828 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4829 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4830
4831 emit_label (label2);
4832
4833 /* allow REG_NOTES to be set on last insn (labels don't have enough
4834 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4835 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8ef30996
MM
4836 DONE;
4837 }
4838}")
4839
8ef30996 4840
bb621ad7
JW
4841(define_expand "fixuns_truncsfdi2"
4842 [(set (match_operand:DI 0 "register_operand" "")
4843 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
46299de9 4844 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4845 "
4846{
bb621ad7
JW
4847 rtx reg1 = gen_reg_rtx (SFmode);
4848 rtx reg2 = gen_reg_rtx (SFmode);
4849 rtx reg3 = gen_reg_rtx (DImode);
4850 rtx label1 = gen_label_rtx ();
4851 rtx label2 = gen_label_rtx ();
eef709c7
KG
4852 REAL_VALUE_TYPE offset;
4853
eaff3bf8 4854 real_2expN (&offset, 63);
8ef30996 4855
bb621ad7 4856 if (reg1) /* turn off complaints about unreached code */
8ef30996 4857 {
5692c7bc 4858 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
bb621ad7 4859 do_pending_stack_adjust ();
8ef30996 4860
bb621ad7
JW
4861 emit_insn (gen_cmpsf (operands[1], reg1));
4862 emit_jump_insn (gen_bge (label1));
8ef30996 4863
bb621ad7 4864 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
c5c76735
JL
4865 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4866 gen_rtx_LABEL_REF (VOIDmode, label2)));
bb621ad7 4867 emit_barrier ();
8ef30996 4868
bb621ad7 4869 emit_label (label1);
c5c76735 4870 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3a6ee9f4 4871 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
bb621ad7 4872 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
8ef30996 4873
bb621ad7
JW
4874 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4875 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
8ef30996 4876
bb621ad7 4877 emit_label (label2);
8ef30996 4878
bb621ad7
JW
4879 /* allow REG_NOTES to be set on last insn (labels don't have enough
4880 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4881 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
bb621ad7 4882 DONE;
8ef30996 4883 }
bb621ad7 4884}")
8ef30996 4885
bb621ad7
JW
4886\f
4887;;
4888;; ....................
4889;;
4890;; DATA MOVEMENT
4891;;
4892;; ....................
8ef30996 4893
cafe096b 4894;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
c5563e11 4895
cafe096b
EC
4896(define_expand "extv"
4897 [(set (match_operand 0 "register_operand" "")
4898 (sign_extract (match_operand:QI 1 "memory_operand" "")
4899 (match_operand 2 "immediate_operand" "")
4900 (match_operand 3 "immediate_operand" "")))]
4901 "!TARGET_MIPS16"
4902 {
4903 if (mips_expand_unaligned_load (operands[0], operands[1],
4904 INTVAL (operands[2]),
4905 INTVAL (operands[3])))
4906 DONE;
4907 else
4908 FAIL;
4909 })
c5563e11 4910
cafe096b
EC
4911(define_expand "extzv"
4912 [(set (match_operand 0 "register_operand" "")
4913 (zero_extract (match_operand:QI 1 "memory_operand" "")
4914 (match_operand 2 "immediate_operand" "")
4915 (match_operand 3 "immediate_operand" "")))]
2bcb2ab3 4916 "!TARGET_MIPS16"
cafe096b
EC
4917 {
4918 if (mips_expand_unaligned_load (operands[0], operands[1],
4919 INTVAL (operands[2]),
4920 INTVAL (operands[3])))
4921 DONE;
4922 else
4923 FAIL;
4924 })
c5563e11 4925
cafe096b
EC
4926(define_expand "insv"
4927 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4928 (match_operand 1 "immediate_operand" "")
4929 (match_operand 2 "immediate_operand" ""))
4930 (match_operand 3 "reg_or_0_operand" ""))]
4931 "!TARGET_MIPS16"
4932 {
4933 if (mips_expand_unaligned_store (operands[0], operands[3],
4934 INTVAL (operands[1]),
4935 INTVAL (operands[2])))
4936 DONE;
4937 else
4938 FAIL;
4939 })
c5563e11 4940
cafe096b
EC
4941;; Unaligned word moves generated by the bit field patterns.
4942;;
4943;; As far as the rtl is concerned, both the left-part and right-part
4944;; instructions can access the whole field. However, the real operand
4945;; refers to just the first or the last byte (depending onendianness).
4946;; We therefore use two memory operands to each instruction, one to
4947;; describe the rtl effect and one to use in the assembly output.
c5563e11 4948
cafe096b
EC
4949(define_insn "mov_lwl"
4950 [(set (match_operand:SI 0 "register_operand" "=d")
4951 (unspec:SI [(match_operand:BLK 1 "general_operand" "m")
4952 (match_operand:QI 2 "general_operand" "m")]
4953 UNSPEC_LWL))]
4954 "!TARGET_MIPS16"
4955 "lwl\t%0,%2"
4956 [(set_attr "type" "load")
4957 (set_attr "mode" "SI")])
c5563e11 4958
cafe096b
EC
4959(define_insn "mov_lwr"
4960 [(set (match_operand:SI 0 "register_operand" "=d")
4961 (unspec:SI [(match_operand:BLK 1 "general_operand" "m")
4962 (match_operand:QI 2 "general_operand" "m")
4963 (match_operand:SI 3 "register_operand" "0")]
4964 UNSPEC_LWR))]
4965 "!TARGET_MIPS16"
4966 "lwr\t%0,%2"
4967 [(set_attr "type" "load")
4968 (set_attr "mode" "SI")])
ed50ab35 4969
0d8e55d8 4970
cafe096b
EC
4971(define_insn "mov_swl"
4972 [(set (match_operand:BLK 0 "memory_operand" "=m")
4973 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4974 (match_operand:QI 2 "general_operand" "m")]
4975 UNSPEC_SWL))]
4976 "!TARGET_MIPS16"
4977 "swl\t%z1,%2"
4978 [(set_attr "type" "store")
4979 (set_attr "mode" "SI")])
0d8e55d8 4980
cafe096b
EC
4981(define_insn "mov_swr"
4982 [(set (match_operand:BLK 0 "memory_operand" "+m")
4983 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4984 (match_operand:QI 2 "general_operand" "m")
4985 (match_dup 0)]
4986 UNSPEC_SWR))]
4987 "!TARGET_MIPS16"
4988 "swr\t%z1,%2"
4989 [(set_attr "type" "store")
4990 (set_attr "mode" "SI")])
0d8e55d8 4991
0d8e55d8 4992
cafe096b
EC
4993(define_insn "mov_ldl"
4994 [(set (match_operand:DI 0 "register_operand" "=d")
4995 (unspec:DI [(match_operand:BLK 1 "general_operand" "m")
4996 (match_operand:QI 2 "general_operand" "m")]
4997 UNSPEC_LDL))]
4998 "TARGET_64BIT && !TARGET_MIPS16"
4999 "ldl\t%0,%2"
5000 [(set_attr "type" "load")
5001 (set_attr "mode" "DI")])
0d8e55d8 5002
cafe096b
EC
5003(define_insn "mov_ldr"
5004 [(set (match_operand:DI 0 "register_operand" "=d")
5005 (unspec:DI [(match_operand:BLK 1 "general_operand" "m")
5006 (match_operand:QI 2 "general_operand" "m")
5007 (match_operand:DI 3 "register_operand" "0")]
5008 UNSPEC_LDR))]
5009 "TARGET_64BIT && !TARGET_MIPS16"
5010 "ldr\t%0,%2"
5011 [(set_attr "type" "load")
5012 (set_attr "mode" "DI")])
0d8e55d8 5013
0d8e55d8 5014
cafe096b
EC
5015(define_insn "mov_sdl"
5016 [(set (match_operand:BLK 0 "memory_operand" "=m")
5017 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
5018 (match_operand:QI 2 "general_operand" "m")]
5019 UNSPEC_SDL))]
5020 "TARGET_64BIT && !TARGET_MIPS16"
5021 "sdl\t%z1,%2"
5022 [(set_attr "type" "store")
5023 (set_attr "mode" "DI")])
0d8e55d8 5024
cafe096b
EC
5025(define_insn "mov_sdr"
5026 [(set (match_operand:BLK 0 "memory_operand" "+m")
5027 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
5028 (match_operand:QI 2 "general_operand" "m")
5029 (match_dup 0)]
5030 UNSPEC_SDR))]
5031 "TARGET_64BIT && !TARGET_MIPS16"
5032 "sdr\t%z1,%2"
5033 [(set_attr "type" "store")
5034 (set_attr "mode" "DI")])
0d8e55d8 5035
0d8e55d8 5036
cafe096b 5037;; Instructions for loading a relocation expression using "lui".
0d8e55d8 5038
cafe096b
EC
5039(define_insn "luisi"
5040 [(set (match_operand:SI 0 "register_operand" "=r")
5041 (unspec:SI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
5042 ""
5043 "lui\t%0,%1"
5044 [(set_attr "type" "arith")])
0d8e55d8 5045
cafe096b
EC
5046(define_insn "luidi"
5047 [(set (match_operand:DI 0 "register_operand" "=r")
5048 (unspec:DI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
5049 "TARGET_64BIT"
5050 "lui\t%0,%1"
5051 [(set_attr "type" "arith")])
aa4e54c4 5052
aa4e54c4 5053
cafe096b
EC
5054;; Instructions for adding the low 16 bits of an address to a register.
5055;; Operand 2 is the address: print_operand works out which relocation
5056;; should be applied.
aa4e54c4 5057
cafe096b 5058(define_insn "lowsi"
aa4e54c4
JW
5059 [(set (match_operand:SI 0 "register_operand" "=r")
5060 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
5061 (match_operand:SI 2 "immediate_operand" "")))]
cafe096b
EC
5062 "!TARGET_MIPS16"
5063 "addiu\\t%0,%1,%R2"
aa4e54c4 5064 [(set_attr "type" "arith")
0ff83799 5065 (set_attr "mode" "SI")])
aa4e54c4 5066
cafe096b
EC
5067(define_insn "lowdi"
5068 [(set (match_operand:DI 0 "register_operand" "=r")
5069 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
5070 (match_operand:DI 2 "immediate_operand" "")))]
5071 "!TARGET_MIPS16 && TARGET_64BIT"
5072 "daddiu\\t%0,%1,%R2"
5073 [(set_attr "type" "arith")
5074 (set_attr "mode" "DI")])
5075
8ef30996
MM
5076;; 64-bit integer moves
5077
5078;; Unlike most other insns, the move insns can't be split with
5079;; different predicates, because register spilling and other parts of
5080;; the compiler, have memoized the insn number already.
5081
ed50ab35
MM
5082(define_expand "movdi"
5083 [(set (match_operand:DI 0 "nonimmediate_operand" "")
cafe096b 5084 (match_operand:DI 1 "" ""))]
ed50ab35
MM
5085 ""
5086 "
5087{
cafe096b
EC
5088 if (mips_legitimize_move (DImode, operands[0], operands[1]))
5089 DONE;
aa4e54c4 5090
e19ff60f
JW
5091 /* If we are generating embedded PIC code, and we are referring to a
5092 symbol in the .text section, we must use an offset from the start
5093 of the function. */
5094 if (TARGET_EMBEDDED_PIC
5095 && (GET_CODE (operands[1]) == LABEL_REF
5096 || (GET_CODE (operands[1]) == SYMBOL_REF
5097 && ! SYMBOL_REF_FLAG (operands[1]))))
5098 {
5099 rtx temp;
5100
5101 temp = embedded_pic_offset (operands[1]);
c8d1b2b7 5102 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
c5c76735 5103 force_reg (DImode, temp));
e19ff60f
JW
5104 emit_move_insn (operands[0], force_reg (DImode, temp));
5105 DONE;
5106 }
ed50ab35
MM
5107}")
5108
2bcb2ab3
GK
5109;; For mips16, we need a special case to handle storing $31 into
5110;; memory, since we don't have a constraint to match $31. This
5111;; instruction can be generated by save_restore_insns.
5112
5113(define_insn ""
cafe096b 5114 [(set (match_operand:DI 0 "memory_operand" "=m")
2bcb2ab3
GK
5115 (reg:DI 31))]
5116 "TARGET_MIPS16 && TARGET_64BIT"
5117 "*
5118{
5119 operands[1] = gen_rtx (REG, DImode, 31);
5120 return mips_move_2words (operands, insn);
5121}"
5122 [(set_attr "type" "store")
cafe096b 5123 (set_attr "mode" "DI")])
2bcb2ab3 5124
ed50ab35 5125(define_insn "movdi_internal"
cafe096b
EC
5126 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
5127 (match_operand:DI 1 "general_operand" "d,iF,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
2bcb2ab3 5128 "!TARGET_64BIT && !TARGET_MIPS16
bb621ad7
JW
5129 && (register_operand (operands[0], DImode)
5130 || register_operand (operands[1], DImode)
5131 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5132 || operands[1] == CONST0_RTX (DImode))"
8ef30996 5133 "* return mips_move_2words (operands, insn); "
cafe096b 5134 [(set_attr "type" "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store")
92b4cee1 5135 (set_attr "mode" "DI")
cafe096b 5136 (set_attr "length" "8,16,*,*,8,8,8,8,*,8,*")])
8ef30996 5137
2bcb2ab3 5138(define_insn ""
cafe096b
EC
5139 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
5140 (match_operand:DI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
2bcb2ab3
GK
5141 "!TARGET_64BIT && TARGET_MIPS16
5142 && (register_operand (operands[0], DImode)
5143 || register_operand (operands[1], DImode))"
5144 "* return mips_move_2words (operands, insn);"
cafe096b 5145 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
2bcb2ab3 5146 (set_attr "mode" "DI")
cafe096b 5147 (set_attr "length" "8,8,8,8,12,*,*,8")])
2bcb2ab3 5148
8ef30996
MM
5149(define_split
5150 [(set (match_operand:DI 0 "register_operand" "")
5151 (match_operand:DI 1 "register_operand" ""))]
2ca2d9ee
EC
5152 "reload_completed && !TARGET_64BIT
5153 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
5154 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5155 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5156
5157 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
ddef6bc7 5158 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
8ef30996
MM
5159 "")
5160
bb621ad7 5161(define_insn "movdi_internal2"
cafe096b
EC
5162 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
5163 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))]
2bcb2ab3 5164 "TARGET_64BIT && !TARGET_MIPS16
bb621ad7 5165 && (register_operand (operands[0], DImode)
8214bf98 5166 || register_operand (operands[1], DImode)
bb621ad7
JW
5167 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5168 || operands[1] == CONST0_RTX (DImode))"
5169 "* return mips_move_2words (operands, insn); "
cafe096b 5170 [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
bb621ad7 5171 (set_attr "mode" "DI")
cafe096b 5172 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")])
225b8835 5173
8214bf98
RS
5174;; Sign-extended operands are reloaded using this instruction, so the
5175;; constraints must handle every SImode source operand X and destination
5176;; register R for which:
5177;;
5178;; mips_secondary_reload_class (CLASS_OF (R), DImode, true,
5179;; gen_rtx_SIGN_EXTEND (DImode, X))
5180;;
5181;; returns NO_REGS. Also handle memory destinations, where allowed.
5182;;
5183;; This pattern is essentially a trimmed-down version of movdi_internal2.
5184;; The main difference is that dJ -> f and f -> d are the only constraints
5185;; involving float registers. See mips_secondary_reload_class for details.
8214bf98
RS
5186
5187(define_insn "*movdi_internal2_mips16"
cafe096b
EC
5188 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
5189 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
2bcb2ab3
GK
5190 "TARGET_64BIT && TARGET_MIPS16
5191 && (register_operand (operands[0], DImode)
cafe096b 5192 || register_operand (operands[1], DImode))"
2bcb2ab3 5193 "* return mips_move_2words (operands, insn);"
cafe096b 5194 [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo")
2bcb2ab3
GK
5195 (set_attr "mode" "DI")
5196 (set_attr_alternative "length"
0ff83799
MM
5197 [(const_int 4)
5198 (const_int 4)
5199 (const_int 4)
2bcb2ab3 5200 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
5201 (const_int 4)
5202 (const_int 8))
2bcb2ab3 5203 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
5204 (const_int 8)
5205 (const_int 12))
cafe096b
EC
5206 (const_string "*")
5207 (const_string "*")
5208 (const_string "*")
0ff83799 5209 (const_int 4)])])
2bcb2ab3 5210
cafe096b 5211
2bcb2ab3
GK
5212;; On the mips16, we can split ld $r,N($r) into an add and a load,
5213;; when the original load is a 4 byte instruction but the add and the
5214;; load are 2 2 byte instructions.
5215
5216(define_split
5217 [(set (match_operand:DI 0 "register_operand" "")
5218 (mem:DI (plus:DI (match_dup 0)
5219 (match_operand:DI 1 "const_int_operand" ""))))]
5220 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
2ca2d9ee 5221 && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
5222 && GET_CODE (operands[0]) == REG
5223 && M16_REG_P (REGNO (operands[0]))
5224 && GET_CODE (operands[1]) == CONST_INT
5225 && ((INTVAL (operands[1]) < 0
5226 && INTVAL (operands[1]) >= -0x10)
5227 || (INTVAL (operands[1]) >= 32 * 8
5228 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
5229 || (INTVAL (operands[1]) >= 0
5230 && INTVAL (operands[1]) < 32 * 8
5231 && (INTVAL (operands[1]) & 7) != 0))"
5232 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
5233 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
5234 "
5235{
5236 HOST_WIDE_INT val = INTVAL (operands[1]);
5237
5238 if (val < 0)
5239 operands[2] = GEN_INT (0);
5240 else if (val >= 32 * 8)
5241 {
5242 int off = val & 7;
5243
5244 operands[1] = GEN_INT (0x8 + off);
5245 operands[2] = GEN_INT (val - off - 0x8);
5246 }
5247 else
5248 {
5249 int off = val & 7;
5250
5251 operands[1] = GEN_INT (off);
5252 operands[2] = GEN_INT (val - off);
5253 }
5254}")
5255
225b8835
ILT
5256;; Handle input reloads in DImode.
5257;; This is mainly to handle reloading HILO_REGNUM. Note that we may
5258;; see it as the source or the destination, depending upon which way
5259;; reload handles the instruction.
5260;; Making the second operand TImode is a trick. The compiler may
5261;; reuse the same register for operand 0 and operand 2. Using TImode
5262;; gives us two registers, so we can always use the one which is not
5263;; used.
5264
5265(define_expand "reload_indi"
5266 [(set (match_operand:DI 0 "register_operand" "=b")
9ec36da5 5267 (match_operand:DI 1 "" "b"))
225b8835
ILT
5268 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5269 "TARGET_64BIT"
5270 "
5271{
c5c76735 5272 rtx scratch = gen_rtx_REG (DImode,
7a38df19 5273 (REGNO (operands[0]) == REGNO (operands[2])
c5c76735
JL
5274 ? REGNO (operands[2]) + 1
5275 : REGNO (operands[2])));
225b8835
ILT
5276
5277 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5278 {
5279 if (GET_CODE (operands[1]) == MEM)
5280 {
404e4854 5281 rtx memword, offword, hi_word, lo_word;
9ec36da5 5282 rtx addr = find_replacement (&XEXP (operands[1], 0));
792760b9 5283 rtx op1 = replace_equiv_address (operands[1], addr);
225b8835 5284
c5c76735 5285 scratch = gen_rtx_REG (SImode, REGNO (scratch));
f4ef873c 5286 memword = adjust_address (op1, SImode, 0);
b72f00af
RK
5287 offword = adjust_address (op1, SImode, 4);
5288
225b8835
ILT
5289 if (BYTES_BIG_ENDIAN)
5290 {
404e4854
KG
5291 hi_word = memword;
5292 lo_word = offword;
225b8835
ILT
5293 }
5294 else
5295 {
404e4854
KG
5296 hi_word = offword;
5297 lo_word = memword;
225b8835 5298 }
404e4854 5299 emit_move_insn (scratch, hi_word);
c5c76735 5300 emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
404e4854 5301 emit_move_insn (scratch, lo_word);
225b8835 5302 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
41f8d041 5303 emit_insn (gen_hilo_delay (operands[0]));
225b8835
ILT
5304 }
5305 else
5306 {
5307 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
c5c76735 5308 emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
225b8835
ILT
5309 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5310 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5311 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
41f8d041 5312 emit_insn (gen_hilo_delay (operands[0]));
225b8835
ILT
5313 }
5314 DONE;
5315 }
5316 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5317 {
c5c76735 5318 emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
225b8835
ILT
5319 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5320 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
c5c76735 5321 emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
225b8835
ILT
5322 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5323 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
41f8d041 5324 emit_insn (gen_hilo_delay (operands[1]));
225b8835
ILT
5325 DONE;
5326 }
5327 /* This handles moves between a float register and HI/LO. */
5328 emit_move_insn (scratch, operands[1]);
5329 emit_move_insn (operands[0], scratch);
5330 DONE;
5331}")
bb621ad7 5332
225b8835
ILT
5333;; Handle output reloads in DImode.
5334
cf877a42
JW
5335;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5336;; use a TImode scratch reg.
5337
225b8835 5338(define_expand "reload_outdi"
3dcaf6e0 5339 [(set (match_operand:DI 0 "general_operand" "=b")
cafe096b 5340 (match_operand:DI 1 "register_operand" "b"))
cf877a42 5341 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
225b8835
ILT
5342 "TARGET_64BIT"
5343 "
5344{
cf877a42
JW
5345 rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5346
225b8835
ILT
5347 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5348 {
cf877a42
JW
5349 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5350 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5351 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5352 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5353 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
41f8d041 5354 emit_insn (gen_hilo_delay (operands[0]));
225b8835
ILT
5355 DONE;
5356 }
5357 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5358 {
5359 if (GET_CODE (operands[0]) == MEM)
5360 {
404e4854 5361 rtx scratch, memword, offword, hi_word, lo_word;
9ec36da5 5362 rtx addr = find_replacement (&XEXP (operands[0], 0));
792760b9 5363 rtx op0 = replace_equiv_address (operands[0], addr);
225b8835 5364
c5c76735 5365 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
f4ef873c 5366 memword = adjust_address (op0, SImode, 0);
b72f00af
RK
5367 offword = adjust_address (op0, SImode, 4);
5368
225b8835
ILT
5369 if (BYTES_BIG_ENDIAN)
5370 {
404e4854
KG
5371 hi_word = memword;
5372 lo_word = offword;
225b8835
ILT
5373 }
5374 else
5375 {
404e4854
KG
5376 hi_word = offword;
5377 lo_word = memword;
225b8835 5378 }
c5c76735 5379 emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
404e4854 5380 emit_move_insn (hi_word, scratch);
c5c76735 5381 emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
404e4854 5382 emit_move_insn (lo_word, scratch);
41f8d041 5383 emit_insn (gen_hilo_delay (operands[1]));
225b8835 5384 }
cf877a42
JW
5385 else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5386 {
5387 /* Handle the case where operand[0] is not a 'd' register,
5388 and hence we can not directly move from the HILO register
5389 into it. */
5390 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5391 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5392 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5393 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5394 emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5395 emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5396 emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5397 emit_insn (gen_movdi (operands[0], scratch));
41f8d041 5398 emit_insn (gen_hilo_delay (operands[1]));
cf877a42 5399 }
225b8835
ILT
5400 else
5401 {
cf877a42
JW
5402 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5403 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5404 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
225b8835
ILT
5405 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5406 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
cf877a42 5407 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
41f8d041 5408 emit_insn (gen_hilo_delay (operands[1]));
225b8835
ILT
5409 }
5410 DONE;
5411 }
5412 /* This handles moves between a float register and HI/LO. */
cf877a42
JW
5413 emit_move_insn (scratch, operands[1]);
5414 emit_move_insn (operands[0], scratch);
225b8835
ILT
5415 DONE;
5416}")
8ef30996
MM
5417
5418;; 32-bit Integer moves
5419
8ef30996
MM
5420;; Unlike most other insns, the move insns can't be split with
5421;; different predicates, because register spilling and other parts of
5422;; the compiler, have memoized the insn number already.
5423
f3b39eba
MM
5424(define_expand "movsi"
5425 [(set (match_operand:SI 0 "nonimmediate_operand" "")
cafe096b 5426 (match_operand:SI 1 "" ""))]
f3b39eba 5427 ""
ed50ab35
MM
5428 "
5429{
cafe096b
EC
5430 if (mips_legitimize_move (SImode, operands[0], operands[1]))
5431 DONE;
aa4e54c4 5432
92544bdf
ILT
5433 /* If we are generating embedded PIC code, and we are referring to a
5434 symbol in the .text section, we must use an offset from the start
5435 of the function. */
5436 if (TARGET_EMBEDDED_PIC
5437 && (GET_CODE (operands[1]) == LABEL_REF
5438 || (GET_CODE (operands[1]) == SYMBOL_REF
5439 && ! SYMBOL_REF_FLAG (operands[1]))))
5440 {
5441 rtx temp;
5442
5443 temp = embedded_pic_offset (operands[1]);
c8d1b2b7 5444 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
c5c76735 5445 force_reg (SImode, temp));
92544bdf
ILT
5446 emit_move_insn (operands[0], force_reg (SImode, temp));
5447 DONE;
5448 }
ed50ab35 5449}")
f3b39eba 5450
07e2e444
AO
5451;; We can only store $ra directly into a small sp offset. Should the
5452;; offset be too wide, non-constant or not sp-based, leave it up to
5453;; reload to choose a scratch register.
2bcb2ab3
GK
5454
5455(define_insn ""
07e2e444
AO
5456 [(set (mem:SI (plus:SI (reg:SI 29)
5457 (match_operand:SI 0 "small_int" "n")))
2bcb2ab3
GK
5458 (reg:SI 31))]
5459 "TARGET_MIPS16"
07e2e444 5460 "sw\\t$31,%0($sp)"
2bcb2ab3
GK
5461 [(set_attr "type" "store")
5462 (set_attr "mode" "SI")
07e2e444
AO
5463 (set_attr_alternative
5464 "length"
33005162 5465 [(if_then_else
07e2e444
AO
5466 (lt (symbol_ref "(unsigned HOST_WIDE_INT) INTVAL (operands[0])")
5467 (const_int 1024))
5468 (const_int 4)
5469 (const_int 8))])])
2bcb2ab3 5470
0fb5ac6f
MM
5471;; The difference between these two is whether or not ints are allowed
5472;; in FP registers (off by default, use -mdebugh to enable).
5473
8214bf98 5474(define_insn "movsi_internal"
cafe096b
EC
5475 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m")
5476 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))]
8214bf98 5477 "!TARGET_MIPS16
ed50ab35
MM
5478 && (register_operand (operands[0], SImode)
5479 || register_operand (operands[1], SImode)
5480 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
bb621ad7 5481 "* return mips_move_1word (operands, insn, FALSE);"
cafe096b 5482 [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
0fb5ac6f 5483 (set_attr "mode" "SI")
cafe096b 5484 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")])
225b8835 5485
2bcb2ab3 5486(define_insn ""
cafe096b
EC
5487 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d")
5488 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x,*a"))]
2bcb2ab3
GK
5489 "TARGET_MIPS16
5490 && (register_operand (operands[0], SImode)
cafe096b 5491 || register_operand (operands[1], SImode))"
2bcb2ab3 5492 "* return mips_move_1word (operands, insn, FALSE);"
cafe096b 5493 [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo,hilo")
2bcb2ab3
GK
5494 (set_attr "mode" "SI")
5495 (set_attr_alternative "length"
0ff83799
MM
5496 [(const_int 4)
5497 (const_int 4)
5498 (const_int 4)
2bcb2ab3 5499 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
5500 (const_int 4)
5501 (const_int 8))
2bcb2ab3 5502 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
5503 (const_int 8)
5504 (const_int 12))
cafe096b
EC
5505 (const_string "*")
5506 (const_string "*")
5507 (const_string "*")
0ff83799
MM
5508 (const_int 4)
5509 (const_int 4)])])
2bcb2ab3
GK
5510
5511;; On the mips16, we can split lw $r,N($r) into an add and a load,
5512;; when the original load is a 4 byte instruction but the add and the
5513;; load are 2 2 byte instructions.
5514
5515(define_split
5516 [(set (match_operand:SI 0 "register_operand" "")
5517 (mem:SI (plus:SI (match_dup 0)
5518 (match_operand:SI 1 "const_int_operand" ""))))]
2ca2d9ee 5519 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
5520 && GET_CODE (operands[0]) == REG
5521 && M16_REG_P (REGNO (operands[0]))
5522 && GET_CODE (operands[1]) == CONST_INT
5523 && ((INTVAL (operands[1]) < 0
5524 && INTVAL (operands[1]) >= -0x80)
5525 || (INTVAL (operands[1]) >= 32 * 4
5526 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5527 || (INTVAL (operands[1]) >= 0
5528 && INTVAL (operands[1]) < 32 * 4
5529 && (INTVAL (operands[1]) & 3) != 0))"
5530 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5531 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
225b8835
ILT
5532 "
5533{
2bcb2ab3
GK
5534 HOST_WIDE_INT val = INTVAL (operands[1]);
5535
5536 if (val < 0)
5537 operands[2] = GEN_INT (0);
5538 else if (val >= 32 * 4)
5539 {
5540 int off = val & 3;
5541
5542 operands[1] = GEN_INT (0x7c + off);
5543 operands[2] = GEN_INT (val - off - 0x7c);
5544 }
5545 else
5546 {
5547 int off = val & 3;
5548
5549 operands[1] = GEN_INT (off);
5550 operands[2] = GEN_INT (val - off);
5551 }
5552}")
5553
5554;; On the mips16, we can split a load of certain constants into a load
5555;; and an add. This turns a 4 byte instruction into 2 2 byte
5556;; instructions.
5557
5558(define_split
5559 [(set (match_operand:SI 0 "register_operand" "")
5560 (match_operand:SI 1 "const_int_operand" ""))]
2ca2d9ee 5561 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
5562 && GET_CODE (operands[0]) == REG
5563 && M16_REG_P (REGNO (operands[0]))
5564 && GET_CODE (operands[1]) == CONST_INT
5565 && INTVAL (operands[1]) >= 0x100
5566 && INTVAL (operands[1]) <= 0xff + 0x7f"
5567 [(set (match_dup 0) (match_dup 1))
5568 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5569 "
5570{
5571 int val = INTVAL (operands[1]);
5572
5573 operands[1] = GEN_INT (0xff);
5574 operands[2] = GEN_INT (val - 0xff);
5575}")
5576
5577;; On the mips16, we can split a load of a negative constant into a
5578;; load and a neg. That's what mips_move_1word will generate anyhow.
5579
5580(define_split
5581 [(set (match_operand:SI 0 "register_operand" "")
5582 (match_operand:SI 1 "const_int_operand" ""))]
2ca2d9ee 5583 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
5584 && GET_CODE (operands[0]) == REG
5585 && M16_REG_P (REGNO (operands[0]))
5586 && GET_CODE (operands[1]) == CONST_INT
5587 && INTVAL (operands[1]) < 0
5588 && INTVAL (operands[1]) > - 0x8000"
5589 [(set (match_dup 0) (match_dup 1))
5590 (set (match_dup 0) (neg:SI (match_dup 0)))]
5591 "
5592{
5593 operands[1] = GEN_INT (- INTVAL (operands[1]));
5594}")
5595
5596;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5597;; order to set the sign bit correctly in the HI register.
5598
5599(define_expand "reload_outsi"
5600 [(set (match_operand:SI 0 "general_operand" "=b")
5601 (match_operand:SI 1 "register_operand" "b"))
5602 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5603 "TARGET_64BIT || TARGET_MIPS16"
5604 "
5605{
5606 if (TARGET_64BIT
5607 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
225b8835 5608 {
c5c76735 5609 emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
225b8835
ILT
5610 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5611 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
41f8d041 5612 emit_insn (gen_hilo_delay (operands[0]));
225b8835
ILT
5613 DONE;
5614 }
2bcb2ab3
GK
5615 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5616 if (TARGET_MIPS16
5617 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5618 {
5619 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5620 /* This is gen_mulsi3_internal, but we need to fill in the
5621 scratch registers. */
5622 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5623 gen_rtvec (3,
5624 gen_rtx (SET, VOIDmode,
5625 operands[0],
5626 gen_rtx (MULT, SImode,
5627 operands[1],
5628 operands[2])),
5629 gen_rtx (CLOBBER, VOIDmode,
5630 gen_rtx (REG, SImode, 64)),
5631 gen_rtx (CLOBBER, VOIDmode,
5632 gen_rtx (REG, SImode, 66)))));
5633 DONE;
5634 }
5635 /* FIXME: I don't know how to get a value into the HI register. */
ca45b913
JW
5636 if (GET_CODE (operands[0]) == REG
5637 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5638 : GP_REG_P (REGNO (operands[0]))))
2bcb2ab3
GK
5639 {
5640 emit_move_insn (operands[0], operands[1]);
5641 DONE;
5642 }
225b8835
ILT
5643 /* This handles moves between a float register and HI/LO. */
5644 emit_move_insn (operands[2], operands[1]);
5645 emit_move_insn (operands[0], operands[2]);
5646 DONE;
5647}")
0fb5ac6f 5648
2bcb2ab3
GK
5649;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5650;; so we use a mult. ??? This is hideous, and we ought to figure out
5651;; something better.
5652
bf4f78ee
JW
5653;; We use no predicate for operand1, because it may be a PLUS, and there
5654;; is no convenient predicate for that.
5655
2bcb2ab3
GK
5656(define_expand "reload_insi"
5657 [(set (match_operand:SI 0 "register_operand" "=b")
bf4f78ee 5658 (match_operand:SI 1 "" "b"))
2bcb2ab3
GK
5659 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5660 "TARGET_MIPS16"
5661 "
5662{
5663 if (TARGET_MIPS16
5664 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5665 {
5666 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5667 /* This is gen_mulsi3_internal, but we need to fill in the
5668 scratch registers. */
5669 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5670 gen_rtvec (3,
5671 gen_rtx (SET, VOIDmode,
5672 operands[0],
5673 gen_rtx (MULT, SImode,
5674 operands[1],
5675 operands[2])),
5676 gen_rtx (CLOBBER, VOIDmode,
5677 gen_rtx (REG, SImode, 64)),
5678 gen_rtx (CLOBBER, VOIDmode,
5679 gen_rtx (REG, SImode, 66)))));
5680 DONE;
5681 }
bf4f78ee
JW
5682
5683 /* If this is a plus, then this must be an add of the stack pointer against
5684 either a hard register or a pseudo. */
5685 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5686 {
5687 rtx plus_op;
5688
5689 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5690 plus_op = XEXP (operands[1], 1);
5691 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5692 plus_op = XEXP (operands[1], 0);
5693 else
5694 abort ();
5695
5696 /* We should have a register now. */
5697 if (GET_CODE (plus_op) != REG)
5698 abort ();
5699
5700 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5701 {
5702 /* We have to have at least one temporary register which is not
5703 overlapping plus_op. */
5704 if (! rtx_equal_p (plus_op, operands[0]))
5705 {
5706 emit_move_insn (operands[0], stack_pointer_rtx);
5707 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5708 }
5709 else if (! rtx_equal_p (plus_op, operands[2]))
5710 {
5711 emit_move_insn (operands[2], stack_pointer_rtx);
5712 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5713 }
5714 else
5715 abort ();
5716 }
5717 else
5718 {
5719 /* We need two registers in this case. */
5720 if (! rtx_equal_p (operands[0], operands[2]))
5721 {
5722 emit_move_insn (operands[0], stack_pointer_rtx);
5723 emit_move_insn (operands[2], plus_op);
5724 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5725 }
5726 else
5727 abort ();
5728 }
5729 DONE;
5730 }
5731
2bcb2ab3
GK
5732 /* FIXME: I don't know how to get a value into the HI register. */
5733 emit_move_insn (operands[0], operands[1]);
5734 DONE;
5735}")
5736
0e5a4ad8
EC
5737;; This insn is for the unspec delay for HILO.
5738
41f8d041
RS
5739(define_insn "hilo_delay"
5740 [(unspec [(match_operand 0 "register_operand" "=b")] UNSPEC_HILO_DELAY)]
0e5a4ad8
EC
5741 ""
5742 ""
5743 [(set_attr "type" "nop")
f1ba94dd
RH
5744 (set_attr "mode" "none")
5745 (set_attr "can_delay" "no")])
0e5a4ad8 5746
b8eb88d0
ILT
5747;; This insn handles moving CCmode values. It's really just a
5748;; slightly simplified copy of movsi_internal2, with additional cases
5749;; to move a condition register to a general register and to move
5750;; between the general registers and the floating point registers.
5751
5752(define_insn "movcc"
cafe096b
EC
5753 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
5754 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
76ee8042 5755 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
b8eb88d0 5756 "* return mips_move_1word (operands, insn, FALSE);"
cafe096b 5757 [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
b8eb88d0 5758 (set_attr "mode" "SI")
cafe096b 5759 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
b8eb88d0 5760
d12b8c85
RS
5761;; Reload condition code registers. reload_incc and reload_outcc
5762;; both handle moves from arbitrary operands into condition code
5763;; registers. reload_incc handles the more common case in which
5764;; a source operand is constrained to be in a condition-code
5765;; register, but has not been allocated to one.
5766;;
5767;; Sometimes, such as in movcc, we have a CCmode destination whose
5768;; constraints do not include 'z'. reload_outcc handles the case
5769;; when such an operand is allocated to a condition-code register.
5770;;
5771;; Note that reloads from a condition code register to some
5772;; other location can be done using ordinary moves. Moving
5773;; into a GPR takes a single movcc, moving elsewhere takes
5774;; two. We can leave these cases to the generic reload code.
b8eb88d0 5775(define_expand "reload_incc"
d12b8c85
RS
5776 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
5777 (match_operand:CC 1 "general_operand" ""))
b8eb88d0 5778 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
76ee8042 5779 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5780 "
5781{
d12b8c85 5782 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
b8eb88d0
ILT
5783 DONE;
5784}")
5785
5786(define_expand "reload_outcc"
d12b8c85
RS
5787 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
5788 (match_operand:CC 1 "register_operand" ""))
5789 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
76ee8042 5790 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5791 "
5792{
d12b8c85 5793 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
b8eb88d0
ILT
5794 DONE;
5795}")
5796
5797;; MIPS4 supports loading and storing a floating point register from
5798;; the sum of two general registers. We use two versions for each of
5799;; these four instructions: one where the two general registers are
5800;; SImode, and one where they are DImode. This is because general
5801;; registers will be in SImode when they hold 32 bit values, but,
5802;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5803;; instructions will still work correctly.
5804
5805;; ??? Perhaps it would be better to support these instructions by
5806;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5807;; these instructions can only be used to load and store floating
5808;; point registers, that would probably cause trouble in reload.
5809
5810(define_insn ""
5811 [(set (match_operand:SF 0 "register_operand" "=f")
5812 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5813 (match_operand:SI 2 "register_operand" "d"))))]
1d5d552e 5814 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5815 "lwxc1\\t%0,%1(%2)"
5816 [(set_attr "type" "load")
cafe096b
EC
5817 (set_attr "mode" "SF")
5818 (set_attr "length" "4")])
b8eb88d0
ILT
5819
5820(define_insn ""
5821 [(set (match_operand:SF 0 "register_operand" "=f")
cafe096b
EC
5822 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
5823 (match_operand:DI 2 "register_operand" "d"))))]
1d5d552e 5824 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5825 "lwxc1\\t%0,%1(%2)"
5826 [(set_attr "type" "load")
cafe096b
EC
5827 (set_attr "mode" "SF")
5828 (set_attr "length" "4")])
b8eb88d0
ILT
5829
5830(define_insn ""
5831 [(set (match_operand:DF 0 "register_operand" "=f")
5832 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5833 (match_operand:SI 2 "register_operand" "d"))))]
1d5d552e 5834 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5835 "ldxc1\\t%0,%1(%2)"
5836 [(set_attr "type" "load")
cafe096b
EC
5837 (set_attr "mode" "DF")
5838 (set_attr "length" "4")])
b8eb88d0
ILT
5839
5840(define_insn ""
5841 [(set (match_operand:DF 0 "register_operand" "=f")
cafe096b
EC
5842 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
5843 (match_operand:DI 2 "register_operand" "d"))))]
1d5d552e 5844 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5845 "ldxc1\\t%0,%1(%2)"
5846 [(set_attr "type" "load")
cafe096b
EC
5847 (set_attr "mode" "DF")
5848 (set_attr "length" "4")])
b8eb88d0
ILT
5849
5850(define_insn ""
5851 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5852 (match_operand:SI 2 "register_operand" "d")))
c5c76735 5853 (match_operand:SF 0 "register_operand" "f"))]
1d5d552e 5854 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5855 "swxc1\\t%0,%1(%2)"
5856 [(set_attr "type" "store")
cafe096b
EC
5857 (set_attr "mode" "SF")
5858 (set_attr "length" "4")])
b8eb88d0
ILT
5859
5860(define_insn ""
cafe096b
EC
5861 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
5862 (match_operand:DI 2 "register_operand" "d")))
c5c76735 5863 (match_operand:SF 0 "register_operand" "f"))]
1d5d552e 5864 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5865 "swxc1\\t%0,%1(%2)"
5866 [(set_attr "type" "store")
cafe096b
EC
5867 (set_attr "mode" "SF")
5868 (set_attr "length" "4")])
b8eb88d0
ILT
5869
5870(define_insn ""
5871 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5872 (match_operand:SI 2 "register_operand" "d")))
c5c76735 5873 (match_operand:DF 0 "register_operand" "f"))]
1d5d552e 5874 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5875 "sdxc1\\t%0,%1(%2)"
5876 [(set_attr "type" "store")
cafe096b
EC
5877 (set_attr "mode" "DF")
5878 (set_attr "length" "4")])
b8eb88d0
ILT
5879
5880(define_insn ""
cafe096b
EC
5881 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
5882 (match_operand:DI 2 "register_operand" "d")))
c5c76735 5883 (match_operand:DF 0 "register_operand" "f"))]
1d5d552e 5884 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5885 "sdxc1\\t%0,%1(%2)"
5886 [(set_attr "type" "store")
cafe096b
EC
5887 (set_attr "mode" "DF")
5888 (set_attr "length" "4")])
b8eb88d0 5889
8ef30996
MM
5890;; 16-bit Integer moves
5891
5892;; Unlike most other insns, the move insns can't be split with
5893;; different predicates, because register spilling and other parts of
5894;; the compiler, have memoized the insn number already.
5895;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5896
0fb5ac6f
MM
5897(define_expand "movhi"
5898 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5899 (match_operand:HI 1 "general_operand" ""))]
8ef30996 5900 ""
ed50ab35
MM
5901 "
5902{
5903 if ((reload_in_progress | reload_completed) == 0
5904 && !register_operand (operands[0], HImode)
5905 && !register_operand (operands[1], HImode)
2bcb2ab3
GK
5906 && (TARGET_MIPS16
5907 || (GET_CODE (operands[1]) != CONST_INT
5908 || INTVAL (operands[1]) != 0)))
ed50ab35
MM
5909 {
5910 rtx temp = force_reg (HImode, operands[1]);
5911 emit_move_insn (operands[0], temp);
5912 DONE;
5913 }
5914}")
0fb5ac6f
MM
5915
5916;; The difference between these two is whether or not ints are allowed
5917;; in FP registers (off by default, use -mdebugh to enable).
5918
8214bf98 5919(define_insn "movhi_internal"
cafe096b
EC
5920 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d")
5921 (match_operand:HI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))]
8214bf98 5922 "!TARGET_MIPS16
ed50ab35
MM
5923 && (register_operand (operands[0], HImode)
5924 || register_operand (operands[1], HImode)
5925 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
8ef30996 5926 "* return mips_move_1word (operands, insn, TRUE);"
cafe096b 5927 [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
92b4cee1 5928 (set_attr "mode" "HI")
cafe096b 5929 (set_attr "length" "4,4,*,*,4,4,4,4,4")])
8ef30996 5930
2bcb2ab3 5931(define_insn ""
cafe096b
EC
5932 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
5933 (match_operand:HI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
2bcb2ab3
GK
5934 "TARGET_MIPS16
5935 && (register_operand (operands[0], HImode)
5936 || register_operand (operands[1], HImode))"
5937 "* return mips_move_1word (operands, insn, TRUE);"
cafe096b 5938 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
2bcb2ab3
GK
5939 (set_attr "mode" "HI")
5940 (set_attr_alternative "length"
0ff83799
MM
5941 [(const_int 4)
5942 (const_int 4)
5943 (const_int 4)
2bcb2ab3 5944 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
5945 (const_int 4)
5946 (const_int 8))
2bcb2ab3 5947 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
5948 (const_int 8)
5949 (const_int 12))
cafe096b
EC
5950 (const_string "*")
5951 (const_string "*")
0ff83799 5952 (const_int 4)])])
2bcb2ab3
GK
5953
5954
5955;; On the mips16, we can split lh $r,N($r) into an add and a load,
5956;; when the original load is a 4 byte instruction but the add and the
5957;; load are 2 2 byte instructions.
5958
5959(define_split
5960 [(set (match_operand:HI 0 "register_operand" "")
988ee12c 5961 (mem:HI (plus:SI (match_dup 0)
2bcb2ab3 5962 (match_operand:SI 1 "const_int_operand" ""))))]
2ca2d9ee 5963 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
5964 && GET_CODE (operands[0]) == REG
5965 && M16_REG_P (REGNO (operands[0]))
5966 && GET_CODE (operands[1]) == CONST_INT
5967 && ((INTVAL (operands[1]) < 0
5968 && INTVAL (operands[1]) >= -0x80)
5969 || (INTVAL (operands[1]) >= 32 * 2
5970 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5971 || (INTVAL (operands[1]) >= 0
5972 && INTVAL (operands[1]) < 32 * 2
5973 && (INTVAL (operands[1]) & 1) != 0))"
5974 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5975 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5976 "
5977{
5978 HOST_WIDE_INT val = INTVAL (operands[1]);
5979
5980 if (val < 0)
5981 operands[2] = GEN_INT (0);
5982 else if (val >= 32 * 2)
5983 {
5984 int off = val & 1;
5985
5986 operands[1] = GEN_INT (0x7e + off);
5987 operands[2] = GEN_INT (val - off - 0x7e);
5988 }
5989 else
5990 {
5991 int off = val & 1;
5992
5993 operands[1] = GEN_INT (off);
5994 operands[2] = GEN_INT (val - off);
5995 }
5996}")
0fb5ac6f 5997
8ef30996
MM
5998;; 8-bit Integer moves
5999
6000;; Unlike most other insns, the move insns can't be split with
6001;; different predicates, because register spilling and other parts of
6002;; the compiler, have memoized the insn number already.
6003;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
6004
0fb5ac6f
MM
6005(define_expand "movqi"
6006 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6007 (match_operand:QI 1 "general_operand" ""))]
8ef30996 6008 ""
ed50ab35
MM
6009 "
6010{
6011 if ((reload_in_progress | reload_completed) == 0
6012 && !register_operand (operands[0], QImode)
6013 && !register_operand (operands[1], QImode)
2bcb2ab3
GK
6014 && (TARGET_MIPS16
6015 || (GET_CODE (operands[1]) != CONST_INT
6016 || INTVAL (operands[1]) != 0)))
ed50ab35
MM
6017 {
6018 rtx temp = force_reg (QImode, operands[1]);
6019 emit_move_insn (operands[0], temp);
6020 DONE;
6021 }
6022}")
0fb5ac6f
MM
6023
6024;; The difference between these two is whether or not ints are allowed
6025;; in FP registers (off by default, use -mdebugh to enable).
6026
8214bf98 6027(define_insn "movqi_internal"
cafe096b
EC
6028 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d")
6029 (match_operand:QI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))]
8214bf98 6030 "!TARGET_MIPS16
ed50ab35
MM
6031 && (register_operand (operands[0], QImode)
6032 || register_operand (operands[1], QImode)
6033 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
8ef30996 6034 "* return mips_move_1word (operands, insn, TRUE);"
cafe096b 6035 [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
92b4cee1 6036 (set_attr "mode" "QI")
cafe096b 6037 (set_attr "length" "4,4,*,*,4,4,4,4,4")])
8ef30996 6038
2bcb2ab3 6039(define_insn ""
cafe096b
EC
6040 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
6041 (match_operand:QI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
2bcb2ab3
GK
6042 "TARGET_MIPS16
6043 && (register_operand (operands[0], QImode)
6044 || register_operand (operands[1], QImode))"
6045 "* return mips_move_1word (operands, insn, TRUE);"
cafe096b 6046 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
2bcb2ab3
GK
6047 (set_attr "mode" "QI")
6048 (set_attr_alternative "length"
0ff83799
MM
6049 [(const_int 4)
6050 (const_int 4)
6051 (const_int 4)
2bcb2ab3 6052 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
6053 (const_int 4)
6054 (const_int 8))
2bcb2ab3 6055 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
6056 (const_int 8)
6057 (const_int 12))
cafe096b
EC
6058 (const_string "*")
6059 (const_string "*")
0ff83799 6060 (const_int 4)])])
2bcb2ab3
GK
6061
6062
6063;; On the mips16, we can split lb $r,N($r) into an add and a load,
6064;; when the original load is a 4 byte instruction but the add and the
6065;; load are 2 2 byte instructions.
6066
6067(define_split
6068 [(set (match_operand:QI 0 "register_operand" "")
6069 (mem:QI (plus:SI (match_dup 0)
6070 (match_operand:SI 1 "const_int_operand" ""))))]
2ca2d9ee 6071 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
6072 && GET_CODE (operands[0]) == REG
6073 && M16_REG_P (REGNO (operands[0]))
6074 && GET_CODE (operands[1]) == CONST_INT
6075 && ((INTVAL (operands[1]) < 0
6076 && INTVAL (operands[1]) >= -0x80)
6077 || (INTVAL (operands[1]) >= 32
6078 && INTVAL (operands[1]) <= 31 + 0x7f))"
6079 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
6080 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
6081 "
6082{
6083 HOST_WIDE_INT val = INTVAL (operands[1]);
6084
6085 if (val < 0)
6086 operands[2] = GEN_INT (0);
6087 else
6088 {
6089 operands[1] = GEN_INT (0x7f);
6090 operands[2] = GEN_INT (val - 0x7f);
6091 }
6092}")
8ef30996
MM
6093
6094;; 32-bit floating point moves
6095
ed50ab35
MM
6096(define_expand "movsf"
6097 [(set (match_operand:SF 0 "nonimmediate_operand" "")
6098 (match_operand:SF 1 "general_operand" ""))]
6099 ""
6100 "
6101{
6102 if ((reload_in_progress | reload_completed) == 0
6103 && !register_operand (operands[0], SFmode)
1f7422bd
RH
6104 && !nonmemory_operand (operands[1], SFmode))
6105 operands[1] = force_reg (SFmode, operands[1]);
ed50ab35
MM
6106}")
6107
b0193a92 6108(define_insn "movsf_internal1"
cafe096b
EC
6109 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
6110 (match_operand:SF 1 "general_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
b0193a92
MM
6111 "TARGET_HARD_FLOAT
6112 && (register_operand (operands[0], SFmode)
1f7422bd 6113 || nonmemory_operand (operands[1], SFmode))"
8ef30996 6114 "* return mips_move_1word (operands, insn, FALSE);"
cafe096b 6115 [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store")
92b4cee1 6116 (set_attr "mode" "SF")
cafe096b 6117 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
8ef30996 6118
b0193a92 6119(define_insn "movsf_internal2"
cafe096b
EC
6120 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
6121 (match_operand:SF 1 "general_operand" " Gd,m,d"))]
2bcb2ab3 6122 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
b0193a92 6123 && (register_operand (operands[0], SFmode)
1f7422bd 6124 || nonmemory_operand (operands[1], SFmode))"
b0193a92 6125 "* return mips_move_1word (operands, insn, FALSE);"
cafe096b 6126 [(set_attr "type" "move,load,store")
b0193a92 6127 (set_attr "mode" "SF")
cafe096b 6128 (set_attr "length" "4,*,*")])
b0193a92 6129
2bcb2ab3 6130(define_insn ""
cafe096b
EC
6131 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
6132 (match_operand:SF 1 "nonimmediate_operand" "d,d,y,m,d"))]
2bcb2ab3
GK
6133 "TARGET_MIPS16
6134 && (register_operand (operands[0], SFmode)
6135 || register_operand (operands[1], SFmode))"
6136 "* return mips_move_1word (operands, insn, FALSE);"
cafe096b 6137 [(set_attr "type" "move,move,move,load,store")
2bcb2ab3 6138 (set_attr "mode" "SF")
cafe096b 6139 (set_attr "length" "4,4,4,*,*")])
2bcb2ab3 6140
b0193a92 6141
8ef30996
MM
6142;; 64-bit floating point moves
6143
ed50ab35
MM
6144(define_expand "movdf"
6145 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6146 (match_operand:DF 1 "general_operand" ""))]
6147 ""
6148 "
6149{
6150 if ((reload_in_progress | reload_completed) == 0
6151 && !register_operand (operands[0], DFmode)
1f7422bd
RH
6152 && !nonmemory_operand (operands[1], DFmode))
6153 operands[1] = force_reg (DFmode, operands[1]);
ed50ab35
MM
6154}")
6155
cafe096b
EC
6156(define_insn "movdf_internal1a"
6157 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
6158 (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
6159 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
b0193a92 6160 && (register_operand (operands[0], DFmode)
1f7422bd 6161 || nonmemory_operand (operands[1], DFmode))"
8ef30996 6162 "* return mips_move_2words (operands, insn); "
cafe096b
EC
6163 [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
6164 (set_attr "mode" "DF")
6165 (set_attr "length" "4,8,*,*,4,4,4,*,*")])
8ef30996 6166
cafe096b
EC
6167(define_insn "movdf_internal1b"
6168 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
6169 (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
6170 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
64d8baf9 6171 && (register_operand (operands[0], DFmode)
1f7422bd 6172 || nonmemory_operand (operands[1], DFmode))"
64d8baf9 6173 "* return mips_move_2words (operands, insn); "
cafe096b 6174 [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
64d8baf9 6175 (set_attr "mode" "DF")
cafe096b 6176 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
64d8baf9 6177
b0193a92 6178(define_insn "movdf_internal2"
cafe096b
EC
6179 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
6180 (match_operand:DF 1 "general_operand" "dG,m,d,f,d,f"))]
2bcb2ab3 6181 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
b0193a92 6182 && (register_operand (operands[0], DFmode)
1f7422bd 6183 || nonmemory_operand (operands[1], DFmode))"
b0193a92 6184 "* return mips_move_2words (operands, insn); "
cafe096b 6185 [(set_attr "type" "move,load,store,xfer,xfer,move")
b0193a92 6186 (set_attr "mode" "DF")
cafe096b 6187 (set_attr "length" "8,*,*,8,8,4")])
b0193a92 6188
2bcb2ab3 6189(define_insn ""
cafe096b
EC
6190 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
6191 (match_operand:DF 1 "nonimmediate_operand" "d,d,y,m,d"))]
2bcb2ab3
GK
6192 "TARGET_MIPS16
6193 && (register_operand (operands[0], DFmode)
6194 || register_operand (operands[1], DFmode))"
6195 "* return mips_move_2words (operands, insn);"
cafe096b 6196 [(set_attr "type" "move,move,move,load,store")
2bcb2ab3 6197 (set_attr "mode" "DF")
cafe096b 6198 (set_attr "length" "8,8,8,*,*")])
2bcb2ab3 6199
8ef30996
MM
6200(define_split
6201 [(set (match_operand:DF 0 "register_operand" "")
6202 (match_operand:DF 1 "register_operand" ""))]
2ca2d9ee
EC
6203 "reload_completed && !TARGET_64BIT
6204 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
6205 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6206 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
8ef30996 6207 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
ddef6bc7 6208 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
8ef30996
MM
6209 "")
6210
e19ff60f
JW
6211;; Instructions to load the global pointer register.
6212;; This is volatile to make sure that the scheduler won't move any symbol_ref
6213;; uses in front of it. All symbol_refs implicitly use the gp reg.
6214
6215(define_insn "loadgp"
6216 [(set (reg:DI 28)
cafe096b 6217 (unspec_volatile:DI [(match_operand 0 "immediate_operand" "")
41f8d041
RS
6218 (match_operand:DI 1 "register_operand" "")]
6219 UNSPEC_LOADGP))
e19ff60f
JW
6220 (clobber (reg:DI 1))]
6221 ""
cafe096b 6222 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%0)))\\n\\tdaddu\\t$gp,$1,%1%]"
e19ff60f
JW
6223 [(set_attr "type" "move")
6224 (set_attr "mode" "DI")
0ff83799 6225 (set_attr "length" "12")])
26b8e6e5 6226\f
8ef30996
MM
6227;; Block moves, see mips.c for more details.
6228;; Argument 0 is the destination
6229;; Argument 1 is the source
6230;; Argument 2 is the length
6231;; Argument 3 is the alignment
6232
6233(define_expand "movstrsi"
e9a25f70
JL
6234 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6235 (match_operand:BLK 1 "general_operand" ""))
8ef30996
MM
6236 (use (match_operand:SI 2 "arith32_operand" ""))
6237 (use (match_operand:SI 3 "immediate_operand" ""))])]
2bcb2ab3 6238 "!TARGET_MIPS16"
8ef30996
MM
6239 "
6240{
6241 if (operands[0]) /* avoid unused code messages */
6242 {
6243 expand_block_move (operands);
6244 DONE;
6245 }
6246}")
6247
842eb20e
MM
6248;; Insn generated by block moves
6249
6250(define_insn "movstrsi_internal"
aa4e54c4
JW
6251 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6252 (match_operand:BLK 1 "memory_operand" "o")) ;; source
26b8e6e5
MM
6253 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6254 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6255 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6256 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6257 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6258 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6259 (use (const_int 0))] ;; normal block move
6260 ""
6261 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
e9a25f70 6262 [(set_attr "type" "store")
842eb20e 6263 (set_attr "mode" "none")
0ff83799 6264 (set_attr "length" "80")])
842eb20e 6265
2bcb2ab3
GK
6266;; We need mips16 versions, because an offset from the stack pointer
6267;; is not offsettable, since the stack pointer can only handle 4 and 8
6268;; byte loads.
6269
2bcb2ab3
GK
6270(define_insn ""
6271 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
cf45bb06 6272 (match_operand:BLK 1 "memory_operand" "o")) ;; source
2bcb2ab3
GK
6273 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6274 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6275 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6276 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6277 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6278 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6279 (use (const_int 0))] ;; normal block move
6280 "TARGET_MIPS16"
6281 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6282 [(set_attr "type" "multi")
6283 (set_attr "mode" "none")
0ff83799 6284 (set_attr "length" "80")])
2bcb2ab3 6285
26b8e6e5
MM
6286;; Split a block move into 2 parts, the first part is everything
6287;; except for the last move, and the second part is just the last
6288;; store, which is exactly 1 instruction (ie, not a usw), so it can
6289;; fill a delay slot. This also prevents a bug in delayed branches
6290;; from showing up, which reuses one of the registers in our clobbers.
6291
1ba8a9c4
RS
6292;; ??? Disabled because it doesn't preserve alias information for
6293;; operands 0 and 1. Also, the rtl for the second insn doesn't mention
6294;; that it uses the registers clobbered by the first.
6295;;
6296;; It would probably be better to split the block into individual
6297;; instructions instead.
26b8e6e5
MM
6298(define_split
6299 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6300 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6301 (clobber (match_operand:SI 4 "register_operand" ""))
6302 (clobber (match_operand:SI 5 "register_operand" ""))
6303 (clobber (match_operand:SI 6 "register_operand" ""))
6304 (clobber (match_operand:SI 7 "register_operand" ""))
6305 (use (match_operand:SI 2 "small_int" ""))
6306 (use (match_operand:SI 3 "small_int" ""))
6307 (use (const_int 0))]
6308
1ba8a9c4 6309 "reload_completed && 0 && INTVAL (operands[2]) > 0"
26b8e6e5
MM
6310
6311 ;; All but the last move
6312 [(parallel [(set (mem:BLK (match_dup 0))
6313 (mem:BLK (match_dup 1)))
6314 (clobber (match_dup 4))
6315 (clobber (match_dup 5))
6316 (clobber (match_dup 6))
6317 (clobber (match_dup 7))
6318 (use (match_dup 2))
6319 (use (match_dup 3))
6320 (use (const_int 1))])
6321
6322 ;; The last store, so it can fill a delay slot
6323 (parallel [(set (mem:BLK (match_dup 0))
6324 (mem:BLK (match_dup 1)))
6325 (clobber (match_dup 4))
6326 (clobber (match_dup 5))
6327 (clobber (match_dup 6))
6328 (clobber (match_dup 7))
6329 (use (match_dup 2))
6330 (use (match_dup 3))
6331 (use (const_int 2))])]
6332
6333 "")
6334
6335(define_insn "movstrsi_internal2"
aa4e54c4
JW
6336 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6337 (match_operand:BLK 1 "memory_operand" "o")) ;; source
26b8e6e5
MM
6338 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6339 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6340 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6341 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6342 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6343 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6344 (use (const_int 1))] ;; all but last store
6345 ""
6346 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
e9a25f70 6347 [(set_attr "type" "store")
26b8e6e5 6348 (set_attr "mode" "none")
0ff83799 6349 (set_attr "length" "80")])
26b8e6e5 6350
2bcb2ab3 6351(define_insn ""
cf45bb06
RH
6352 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6353 (match_operand:BLK 1 "memory_operand" "o")) ;; source
2bcb2ab3
GK
6354 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6355 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6356 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6357 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6358 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6359 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6360 (use (const_int 1))] ;; all but last store
6361 "TARGET_MIPS16"
6362 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6363 [(set_attr "type" "multi")
6364 (set_attr "mode" "none")
0ff83799 6365 (set_attr "length" "80")])
2bcb2ab3 6366
26b8e6e5 6367(define_insn "movstrsi_internal3"
cafe096b
EC
6368 [(set (match_operand:BLK 0 "memory_operand" "=m") ;; destination
6369 (match_operand:BLK 1 "memory_operand" "m")) ;; source
26b8e6e5
MM
6370 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6371 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6372 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6373 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6374 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6375 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
bb621ad7 6376 (use (const_int 2))] ;; just last store of block move
26b8e6e5
MM
6377 ""
6378 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6379 [(set_attr "type" "store")
0ff83799 6380 (set_attr "mode" "none")])
8ef30996
MM
6381\f
6382;;
6383;; ....................
6384;;
6385;; SHIFTS
6386;;
6387;; ....................
6388
2bcb2ab3
GK
6389;; Many of these instructions uses trivial define_expands, because we
6390;; want to use a different set of constraints when TARGET_MIPS16.
6391
6392(define_expand "ashlsi3"
8ef30996
MM
6393 [(set (match_operand:SI 0 "register_operand" "=d")
6394 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6395 (match_operand:SI 2 "arith_operand" "dI")))]
6396 ""
2bcb2ab3
GK
6397 "
6398{
6399 /* On the mips16, a shift of more than 8 is a four byte instruction,
6400 so, for a shift between 8 and 16, it is just as fast to do two
6401 shifts of 8 or less. If there is a lot of shifting going on, we
6402 may win in CSE. Otherwise combine will put the shifts back
6403 together again. This can be called by function_arg, so we must
6404 be careful not to allocate a new register if we've reached the
6405 reload pass. */
6406 if (TARGET_MIPS16
6407 && optimize
6408 && GET_CODE (operands[2]) == CONST_INT
6409 && INTVAL (operands[2]) > 8
6410 && INTVAL (operands[2]) <= 16
6411 && ! reload_in_progress
6412 && ! reload_completed)
6413 {
6414 rtx temp = gen_reg_rtx (SImode);
6415
6416 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6417 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6418 GEN_INT (INTVAL (operands[2]) - 8)));
6419 DONE;
6420 }
6421}")
6422
6423(define_insn "ashlsi3_internal1"
6424 [(set (match_operand:SI 0 "register_operand" "=d")
6425 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6426 (match_operand:SI 2 "arith_operand" "dI")))]
6427 "!TARGET_MIPS16"
8ef30996
MM
6428 "*
6429{
6430 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 6431 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6432
6433 return \"sll\\t%0,%1,%2\";
6434}"
6435 [(set_attr "type" "arith")
0ff83799 6436 (set_attr "mode" "SI")])
8ef30996 6437
cafe096b
EC
6438(define_insn "ashlsi3_internal1_extend"
6439 [(set (match_operand:DI 0 "register_operand" "=d")
6440 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
6441 (match_operand:SI 2 "arith_operand" "dI"))))]
6442 "TARGET_64BIT && !TARGET_MIPS16"
6443 "*
6444{
6445 if (GET_CODE (operands[2]) == CONST_INT)
6446 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6447
6448 return \"sll\\t%0,%1,%2\";
6449}"
6450 [(set_attr "type" "arith")
6451 (set_attr "mode" "DI")])
6452
6453
2bcb2ab3
GK
6454(define_insn "ashlsi3_internal2"
6455 [(set (match_operand:SI 0 "register_operand" "=d,d")
6456 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6457 (match_operand:SI 2 "arith_operand" "d,I")))]
6458 "TARGET_MIPS16"
6459 "*
6460{
6461 if (which_alternative == 0)
6462 return \"sll\\t%0,%2\";
6463
6464 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 6465 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2bcb2ab3
GK
6466
6467 return \"sll\\t%0,%1,%2\";
6468}"
6469 [(set_attr "type" "arith")
6470 (set_attr "mode" "SI")
6471 (set_attr_alternative "length"
0ff83799 6472 [(const_int 4)
2bcb2ab3 6473 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
6474 (const_int 4)
6475 (const_int 8))])])
2bcb2ab3
GK
6476
6477;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6478
6479(define_split
6480 [(set (match_operand:SI 0 "register_operand" "")
6481 (ashift:SI (match_operand:SI 1 "register_operand" "")
6482 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 6483 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
6484 && GET_CODE (operands[2]) == CONST_INT
6485 && INTVAL (operands[2]) > 8
6486 && INTVAL (operands[2]) <= 16"
6487 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6488 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6489"
6490{
6491 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6492}")
8ef30996
MM
6493
6494(define_expand "ashldi3"
6495 [(parallel [(set (match_operand:DI 0 "register_operand" "")
cafe096b 6496 (ashift:DI (match_operand:DI 1 "register_operand" "")
8ef30996
MM
6497 (match_operand:SI 2 "arith_operand" "")))
6498 (clobber (match_dup 3))])]
2bcb2ab3 6499 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
6500 "
6501{
6502 if (TARGET_64BIT)
6503 {
2bcb2ab3
GK
6504 /* On the mips16, a shift of more than 8 is a four byte
6505 instruction, so, for a shift between 8 and 16, it is just as
6506 fast to do two shifts of 8 or less. If there is a lot of
6507 shifting going on, we may win in CSE. Otherwise combine will
6508 put the shifts back together again. This can be called by
6509 function_arg, so we must be careful not to allocate a new
6510 register if we've reached the reload pass. */
6511 if (TARGET_MIPS16
6512 && optimize
6513 && GET_CODE (operands[2]) == CONST_INT
6514 && INTVAL (operands[2]) > 8
6515 && INTVAL (operands[2]) <= 16
6516 && ! reload_in_progress
6517 && ! reload_completed)
6518 {
6519 rtx temp = gen_reg_rtx (DImode);
6520
6521 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6522 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6523 GEN_INT (INTVAL (operands[2]) - 8)));
6524 DONE;
6525 }
6526
bb621ad7
JW
6527 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6528 operands[2]));
6529 DONE;
6530 }
6531
6532 operands[3] = gen_reg_rtx (SImode);
6533}")
8ef30996
MM
6534
6535
6536(define_insn "ashldi3_internal"
0fb5ac6f 6537 [(set (match_operand:DI 0 "register_operand" "=&d")
8ef30996
MM
6538 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6539 (match_operand:SI 2 "register_operand" "d")))
6540 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6541 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7a38df19 6542 "*
8ef30996
MM
6543{
6544 operands[4] = const0_rtx;
6545 dslots_jump_total += 3;
6546 dslots_jump_filled += 2;
6547
6548 return \"sll\\t%3,%2,26\\n\\
6549\\tbgez\\t%3,1f\\n\\
6550\\tsll\\t%M0,%L1,%2\\n\\
6551\\t%(b\\t3f\\n\\
6552\\tmove\\t%L0,%z4%)\\n\\
6553\\n\\
efa3896a 6554%~1:\\n\\
8ef30996
MM
6555\\t%(beq\\t%3,%z4,2f\\n\\
6556\\tsll\\t%M0,%M1,%2%)\\n\\
6557\\n\\
6558\\tsubu\\t%3,%z4,%2\\n\\
6559\\tsrl\\t%3,%L1,%3\\n\\
6560\\tor\\t%M0,%M0,%3\\n\\
efa3896a 6561%~2:\\n\\
8ef30996 6562\\tsll\\t%L0,%L1,%2\\n\\
efa3896a 6563%~3:\";
8ef30996
MM
6564}"
6565 [(set_attr "type" "darith")
6566 (set_attr "mode" "SI")
0ff83799 6567 (set_attr "length" "48")])
8ef30996
MM
6568
6569
6570(define_insn "ashldi3_internal2"
6571 [(set (match_operand:DI 0 "register_operand" "=d")
6572 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6573 (match_operand:SI 2 "small_int" "IJK")))
6574 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3
GK
6575 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6576 && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
6577 "*
6578{
95936d18 6579 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6580 operands[4] = const0_rtx;
6581 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6582}"
6583 [(set_attr "type" "darith")
6584 (set_attr "mode" "DI")
0ff83799 6585 (set_attr "length" "8")])
8ef30996
MM
6586
6587
6588(define_split
6589 [(set (match_operand:DI 0 "register_operand" "")
6590 (ashift:DI (match_operand:DI 1 "register_operand" "")
6591 (match_operand:SI 2 "small_int" "")))
6592 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6593 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6594 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6595 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6596 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6597 && (INTVAL (operands[2]) & 32) != 0"
6598
ddef6bc7 6599 [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
8ef30996
MM
6600 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6601
95936d18 6602 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6603
6604
6605(define_split
6606 [(set (match_operand:DI 0 "register_operand" "")
6607 (ashift:DI (match_operand:DI 1 "register_operand" "")
6608 (match_operand:SI 2 "small_int" "")))
6609 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6610 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6611 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6612 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6613 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6614 && (INTVAL (operands[2]) & 32) != 0"
6615
ddef6bc7
JJ
6616 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6617 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
8ef30996 6618
95936d18 6619 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6620
6621
6622(define_insn "ashldi3_internal3"
6623 [(set (match_operand:DI 0 "register_operand" "=d")
6624 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6625 (match_operand:SI 2 "small_int" "IJK")))
6626 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6627 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6628 && (INTVAL (operands[2]) & 63) < 32
6629 && (INTVAL (operands[2]) & 63) != 0"
6630 "*
6631{
6632 int amount = INTVAL (operands[2]);
6633
c5c76735 6634 operands[2] = GEN_INT (amount & 31);
8ef30996 6635 operands[4] = const0_rtx;
c5c76735 6636 operands[5] = GEN_INT ((-amount) & 31);
8ef30996
MM
6637
6638 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6639}"
6640 [(set_attr "type" "darith")
6641 (set_attr "mode" "DI")
0ff83799 6642 (set_attr "length" "16")])
8ef30996
MM
6643
6644
6645(define_split
6646 [(set (match_operand:DI 0 "register_operand" "")
6647 (ashift:DI (match_operand:DI 1 "register_operand" "")
6648 (match_operand:SI 2 "small_int" "")))
6649 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6650 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6651 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6652 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6653 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6654 && (INTVAL (operands[2]) & 63) < 32
6655 && (INTVAL (operands[2]) & 63) != 0"
6656
ddef6bc7
JJ
6657 [(set (subreg:SI (match_dup 0) 4)
6658 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6659 (match_dup 2)))
6660
6661 (set (match_dup 3)
6662 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6663 (match_dup 4)))
6664
ddef6bc7
JJ
6665 (set (subreg:SI (match_dup 0) 4)
6666 (ior:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
6667 (match_dup 3)))
6668
6669 (set (subreg:SI (match_dup 0) 0)
6670 (ashift:SI (subreg:SI (match_dup 1) 0)
6671 (match_dup 2)))]
6672 "
6673{
6674 int amount = INTVAL (operands[2]);
c5c76735
JL
6675 operands[2] = GEN_INT (amount & 31);
6676 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6677}")
6678
6679
6680(define_split
6681 [(set (match_operand:DI 0 "register_operand" "")
6682 (ashift:DI (match_operand:DI 1 "register_operand" "")
6683 (match_operand:SI 2 "small_int" "")))
6684 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6685 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6686 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6687 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6688 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6689 && (INTVAL (operands[2]) & 63) < 32
6690 && (INTVAL (operands[2]) & 63) != 0"
6691
6692 [(set (subreg:SI (match_dup 0) 0)
6693 (ashift:SI (subreg:SI (match_dup 1) 0)
6694 (match_dup 2)))
6695
6696 (set (match_dup 3)
ddef6bc7 6697 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6698 (match_dup 4)))
6699
6700 (set (subreg:SI (match_dup 0) 0)
6701 (ior:SI (subreg:SI (match_dup 0) 0)
6702 (match_dup 3)))
6703
ddef6bc7
JJ
6704 (set (subreg:SI (match_dup 0) 4)
6705 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6706 (match_dup 2)))]
6707 "
6708{
6709 int amount = INTVAL (operands[2]);
c5c76735
JL
6710 operands[2] = GEN_INT (amount & 31);
6711 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6712}")
6713
6714
bb621ad7
JW
6715(define_insn "ashldi3_internal4"
6716 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 6717 (ashift:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 6718 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 6719 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
6720 "*
6721{
6722 if (GET_CODE (operands[2]) == CONST_INT)
6723 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6724
6725 return \"dsll\\t%0,%1,%2\";
6726}"
6727 [(set_attr "type" "arith")
0ff83799 6728 (set_attr "mode" "DI")])
bb621ad7 6729
2bcb2ab3
GK
6730(define_insn ""
6731 [(set (match_operand:DI 0 "register_operand" "=d,d")
cafe096b 6732 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
2bcb2ab3
GK
6733 (match_operand:SI 2 "arith_operand" "d,I")))]
6734 "TARGET_64BIT && TARGET_MIPS16"
6735 "*
6736{
6737 if (which_alternative == 0)
6738 return \"dsll\\t%0,%2\";
6739
6740 if (GET_CODE (operands[2]) == CONST_INT)
6741 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6742
6743 return \"dsll\\t%0,%1,%2\";
6744}"
6745 [(set_attr "type" "arith")
6746 (set_attr "mode" "DI")
6747 (set_attr_alternative "length"
0ff83799 6748 [(const_int 4)
2bcb2ab3 6749 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
6750 (const_int 4)
6751 (const_int 8))])])
2bcb2ab3 6752
bb621ad7 6753
2bcb2ab3
GK
6754;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6755
6756(define_split
6757 [(set (match_operand:DI 0 "register_operand" "")
6758 (ashift:DI (match_operand:DI 1 "register_operand" "")
6759 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 6760 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
6761 && reload_completed
6762 && GET_CODE (operands[2]) == CONST_INT
6763 && INTVAL (operands[2]) > 8
6764 && INTVAL (operands[2]) <= 16"
6765 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6766 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6767"
6768{
6769 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6770}")
6771
6772(define_expand "ashrsi3"
8ef30996
MM
6773 [(set (match_operand:SI 0 "register_operand" "=d")
6774 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6775 (match_operand:SI 2 "arith_operand" "dI")))]
6776 ""
2bcb2ab3
GK
6777 "
6778{
6779 /* On the mips16, a shift of more than 8 is a four byte instruction,
6780 so, for a shift between 8 and 16, it is just as fast to do two
6781 shifts of 8 or less. If there is a lot of shifting going on, we
6782 may win in CSE. Otherwise combine will put the shifts back
6783 together again. */
6784 if (TARGET_MIPS16
6785 && optimize
6786 && GET_CODE (operands[2]) == CONST_INT
6787 && INTVAL (operands[2]) > 8
6788 && INTVAL (operands[2]) <= 16)
6789 {
6790 rtx temp = gen_reg_rtx (SImode);
6791
6792 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6793 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6794 GEN_INT (INTVAL (operands[2]) - 8)));
6795 DONE;
6796 }
6797}")
6798
6799(define_insn "ashrsi3_internal1"
6800 [(set (match_operand:SI 0 "register_operand" "=d")
6801 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6802 (match_operand:SI 2 "arith_operand" "dI")))]
6803 "!TARGET_MIPS16"
8ef30996
MM
6804 "*
6805{
6806 if (GET_CODE (operands[2]) == CONST_INT)
2bcb2ab3 6807 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6808
6809 return \"sra\\t%0,%1,%2\";
6810}"
6811 [(set_attr "type" "arith")
0ff83799 6812 (set_attr "mode" "SI")])
8ef30996 6813
2bcb2ab3
GK
6814(define_insn "ashrsi3_internal2"
6815 [(set (match_operand:SI 0 "register_operand" "=d,d")
6816 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6817 (match_operand:SI 2 "arith_operand" "d,I")))]
6818 "TARGET_MIPS16"
6819 "*
6820{
6821 if (which_alternative == 0)
6822 return \"sra\\t%0,%2\";
6823
6824 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 6825 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2bcb2ab3
GK
6826
6827 return \"sra\\t%0,%1,%2\";
6828}"
6829 [(set_attr "type" "arith")
6830 (set_attr "mode" "SI")
6831 (set_attr_alternative "length"
0ff83799 6832 [(const_int 4)
2bcb2ab3 6833 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
6834 (const_int 4)
6835 (const_int 8))])])
2bcb2ab3
GK
6836
6837
6838;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6839
6840(define_split
6841 [(set (match_operand:SI 0 "register_operand" "")
6842 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6843 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 6844 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
6845 && GET_CODE (operands[2]) == CONST_INT
6846 && INTVAL (operands[2]) > 8
6847 && INTVAL (operands[2]) <= 16"
6848 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6849 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6850"
6851{
6852 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6853}")
8ef30996
MM
6854
6855(define_expand "ashrdi3"
6856 [(parallel [(set (match_operand:DI 0 "register_operand" "")
cafe096b 6857 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8ef30996
MM
6858 (match_operand:SI 2 "arith_operand" "")))
6859 (clobber (match_dup 3))])]
2bcb2ab3 6860 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
6861 "
6862{
6863 if (TARGET_64BIT)
6864 {
2bcb2ab3
GK
6865 /* On the mips16, a shift of more than 8 is a four byte
6866 instruction, so, for a shift between 8 and 16, it is just as
6867 fast to do two shifts of 8 or less. If there is a lot of
6868 shifting going on, we may win in CSE. Otherwise combine will
6869 put the shifts back together again. */
6870 if (TARGET_MIPS16
6871 && optimize
6872 && GET_CODE (operands[2]) == CONST_INT
6873 && INTVAL (operands[2]) > 8
6874 && INTVAL (operands[2]) <= 16)
6875 {
6876 rtx temp = gen_reg_rtx (DImode);
6877
6878 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6879 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6880 GEN_INT (INTVAL (operands[2]) - 8)));
6881 DONE;
6882 }
6883
bb621ad7
JW
6884 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6885 operands[2]));
6886 DONE;
6887 }
6888
6889 operands[3] = gen_reg_rtx (SImode);
6890}")
8ef30996
MM
6891
6892
6893(define_insn "ashrdi3_internal"
0fb5ac6f 6894 [(set (match_operand:DI 0 "register_operand" "=&d")
8ef30996
MM
6895 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6896 (match_operand:SI 2 "register_operand" "d")))
6897 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6898 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7a38df19 6899 "*
8ef30996
MM
6900{
6901 operands[4] = const0_rtx;
6902 dslots_jump_total += 3;
6903 dslots_jump_filled += 2;
6904
6905 return \"sll\\t%3,%2,26\\n\\
6906\\tbgez\\t%3,1f\\n\\
6907\\tsra\\t%L0,%M1,%2\\n\\
6908\\t%(b\\t3f\\n\\
6909\\tsra\\t%M0,%M1,31%)\\n\\
6910\\n\\
efa3896a 6911%~1:\\n\\
8ef30996
MM
6912\\t%(beq\\t%3,%z4,2f\\n\\
6913\\tsrl\\t%L0,%L1,%2%)\\n\\
6914\\n\\
6915\\tsubu\\t%3,%z4,%2\\n\\
6916\\tsll\\t%3,%M1,%3\\n\\
6917\\tor\\t%L0,%L0,%3\\n\\
efa3896a 6918%~2:\\n\\
8ef30996 6919\\tsra\\t%M0,%M1,%2\\n\\
efa3896a 6920%~3:\";
8ef30996
MM
6921}"
6922 [(set_attr "type" "darith")
6923 (set_attr "mode" "DI")
0ff83799 6924 (set_attr "length" "48")])
8ef30996
MM
6925
6926
6927(define_insn "ashrdi3_internal2"
6928 [(set (match_operand:DI 0 "register_operand" "=d")
6929 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6930 (match_operand:SI 2 "small_int" "IJK")))
6931 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 6932 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
6933 "*
6934{
95936d18 6935 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6936 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6937}"
6938 [(set_attr "type" "darith")
6939 (set_attr "mode" "DI")
0ff83799 6940 (set_attr "length" "8")])
8ef30996
MM
6941
6942
6943(define_split
6944 [(set (match_operand:DI 0 "register_operand" "")
6945 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6946 (match_operand:SI 2 "small_int" "")))
6947 (clobber (match_operand:SI 3 "register_operand" ""))]
2ca2d9ee
EC
6948 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6949 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
6950 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6951 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6952 && (INTVAL (operands[2]) & 32) != 0"
6953
ddef6bc7
JJ
6954 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6955 (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
8ef30996 6956
95936d18 6957 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6958
6959
6960(define_split
6961 [(set (match_operand:DI 0 "register_operand" "")
6962 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6963 (match_operand:SI 2 "small_int" "")))
6964 (clobber (match_operand:SI 3 "register_operand" ""))]
2ca2d9ee
EC
6965 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6966 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
6967 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6968 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6969 && (INTVAL (operands[2]) & 32) != 0"
6970
ddef6bc7 6971 [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
8ef30996
MM
6972 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6973
95936d18 6974 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6975
6976
6977(define_insn "ashrdi3_internal3"
6978 [(set (match_operand:DI 0 "register_operand" "=d")
6979 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6980 (match_operand:SI 2 "small_int" "IJK")))
6981 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6982 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6983 && (INTVAL (operands[2]) & 63) < 32
6984 && (INTVAL (operands[2]) & 63) != 0"
6985 "*
6986{
6987 int amount = INTVAL (operands[2]);
6988
c5c76735
JL
6989 operands[2] = GEN_INT (amount & 31);
6990 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6991
6992 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
6993}"
6994 [(set_attr "type" "darith")
6995 (set_attr "mode" "DI")
0ff83799 6996 (set_attr "length" "16")])
8ef30996
MM
6997
6998
6999(define_split
7000 [(set (match_operand:DI 0 "register_operand" "")
7001 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7002 (match_operand:SI 2 "small_int" "")))
7003 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7004 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7005 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7006 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7007 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7008 && (INTVAL (operands[2]) & 63) < 32
7009 && (INTVAL (operands[2]) & 63) != 0"
7010
7011 [(set (subreg:SI (match_dup 0) 0)
7012 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7013 (match_dup 2)))
7014
7015 (set (match_dup 3)
ddef6bc7 7016 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7017 (match_dup 4)))
7018
7019 (set (subreg:SI (match_dup 0) 0)
7020 (ior:SI (subreg:SI (match_dup 0) 0)
7021 (match_dup 3)))
7022
ddef6bc7
JJ
7023 (set (subreg:SI (match_dup 0) 4)
7024 (ashiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7025 (match_dup 2)))]
7026 "
7027{
7028 int amount = INTVAL (operands[2]);
c5c76735
JL
7029 operands[2] = GEN_INT (amount & 31);
7030 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7031}")
7032
7033
7034(define_split
7035 [(set (match_operand:DI 0 "register_operand" "")
7036 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7037 (match_operand:SI 2 "small_int" "")))
7038 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7039 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7040 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7041 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7042 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7043 && (INTVAL (operands[2]) & 63) < 32
7044 && (INTVAL (operands[2]) & 63) != 0"
7045
ddef6bc7
JJ
7046 [(set (subreg:SI (match_dup 0) 4)
7047 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7048 (match_dup 2)))
7049
7050 (set (match_dup 3)
7051 (ashift:SI (subreg:SI (match_dup 1) 0)
7052 (match_dup 4)))
7053
ddef6bc7
JJ
7054 (set (subreg:SI (match_dup 0) 4)
7055 (ior:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
7056 (match_dup 3)))
7057
7058 (set (subreg:SI (match_dup 0) 0)
7059 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
7060 (match_dup 2)))]
7061 "
7062{
7063 int amount = INTVAL (operands[2]);
c5c76735
JL
7064 operands[2] = GEN_INT (amount & 31);
7065 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7066}")
7067
7068
bb621ad7
JW
7069(define_insn "ashrdi3_internal4"
7070 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 7071 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 7072 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 7073 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
7074 "*
7075{
7076 if (GET_CODE (operands[2]) == CONST_INT)
7077 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7078
7079 return \"dsra\\t%0,%1,%2\";
7080}"
7081 [(set_attr "type" "arith")
0ff83799 7082 (set_attr "mode" "DI")])
bb621ad7 7083
2bcb2ab3
GK
7084(define_insn ""
7085 [(set (match_operand:DI 0 "register_operand" "=d,d")
cafe096b 7086 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
2bcb2ab3
GK
7087 (match_operand:SI 2 "arith_operand" "d,I")))]
7088 "TARGET_64BIT && TARGET_MIPS16"
7089 "*
7090{
7091 if (GET_CODE (operands[2]) == CONST_INT)
7092 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7093
7094 return \"dsra\\t%0,%2\";
7095}"
7096 [(set_attr "type" "arith")
7097 (set_attr "mode" "DI")
7098 (set_attr_alternative "length"
0ff83799 7099 [(const_int 4)
2bcb2ab3 7100 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7101 (const_int 4)
7102 (const_int 8))])])
2bcb2ab3
GK
7103
7104;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
bb621ad7 7105
2bcb2ab3
GK
7106(define_split
7107 [(set (match_operand:DI 0 "register_operand" "")
7108 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7109 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 7110 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
7111 && reload_completed
7112 && GET_CODE (operands[2]) == CONST_INT
7113 && INTVAL (operands[2]) > 8
7114 && INTVAL (operands[2]) <= 16"
7115 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7116 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7117"
7118{
7119 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7120}")
7121
7122(define_expand "lshrsi3"
8ef30996
MM
7123 [(set (match_operand:SI 0 "register_operand" "=d")
7124 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7125 (match_operand:SI 2 "arith_operand" "dI")))]
7126 ""
2bcb2ab3
GK
7127 "
7128{
7129 /* On the mips16, a shift of more than 8 is a four byte instruction,
7130 so, for a shift between 8 and 16, it is just as fast to do two
7131 shifts of 8 or less. If there is a lot of shifting going on, we
7132 may win in CSE. Otherwise combine will put the shifts back
7133 together again. */
7134 if (TARGET_MIPS16
7135 && optimize
7136 && GET_CODE (operands[2]) == CONST_INT
7137 && INTVAL (operands[2]) > 8
7138 && INTVAL (operands[2]) <= 16)
7139 {
7140 rtx temp = gen_reg_rtx (SImode);
7141
7142 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7143 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7144 GEN_INT (INTVAL (operands[2]) - 8)));
7145 DONE;
7146 }
7147}")
7148
7149(define_insn "lshrsi3_internal1"
7150 [(set (match_operand:SI 0 "register_operand" "=d")
7151 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7152 (match_operand:SI 2 "arith_operand" "dI")))]
7153 "!TARGET_MIPS16"
8ef30996
MM
7154 "*
7155{
7156 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 7157 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
7158
7159 return \"srl\\t%0,%1,%2\";
7160}"
7161 [(set_attr "type" "arith")
0ff83799 7162 (set_attr "mode" "SI")])
8ef30996 7163
2bcb2ab3
GK
7164(define_insn "lshrsi3_internal2"
7165 [(set (match_operand:SI 0 "register_operand" "=d,d")
7166 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7167 (match_operand:SI 2 "arith_operand" "d,I")))]
7168 "TARGET_MIPS16"
7169 "*
7170{
7171 if (which_alternative == 0)
7172 return \"srl\\t%0,%2\";
7173
7174 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 7175 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2bcb2ab3
GK
7176
7177 return \"srl\\t%0,%1,%2\";
7178}"
7179 [(set_attr "type" "arith")
7180 (set_attr "mode" "SI")
7181 (set_attr_alternative "length"
0ff83799 7182 [(const_int 4)
2bcb2ab3 7183 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7184 (const_int 4)
7185 (const_int 8))])])
2bcb2ab3
GK
7186
7187
7188;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7189
7190(define_split
7191 [(set (match_operand:SI 0 "register_operand" "")
7192 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7193 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 7194 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
7195 && GET_CODE (operands[2]) == CONST_INT
7196 && INTVAL (operands[2]) > 8
7197 && INTVAL (operands[2]) <= 16"
7198 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7199 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7200"
7201{
7202 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7203}")
7204
7205;; If we load a byte on the mips16 as a bitfield, the resulting
7206;; sequence of instructions is too complicated for combine, because it
7207;; involves four instructions: a load, a shift, a constant load into a
7208;; register, and an and (the key problem here is that the mips16 does
7209;; not have and immediate). We recognize a shift of a load in order
7210;; to make it simple enough for combine to understand.
7211
cafe096b 7212;; ??? FIXME: turn into a define_insn_and_split
2bcb2ab3 7213(define_insn ""
cafe096b
EC
7214 [(set (match_operand:SI 0 "register_operand" "=d")
7215 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
7216 (match_operand:SI 2 "immediate_operand" "I")))]
7217 "0 && TARGET_MIPS16"
2bcb2ab3
GK
7218 "lw\\t%0,%1\;srl\\t%0,%2"
7219 [(set_attr "type" "load")
7220 (set_attr "mode" "SI")
7221 (set_attr_alternative "length"
7222 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7223 (const_int 12)
7224 (const_int 16))])])
2bcb2ab3
GK
7225
7226(define_split
7227 [(set (match_operand:SI 0 "register_operand" "")
7228 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7229 (match_operand:SI 2 "immediate_operand" "")))]
2ca2d9ee 7230 "TARGET_MIPS16 && !TARGET_DEBUG_D_MODE"
2bcb2ab3
GK
7231 [(set (match_dup 0) (match_dup 1))
7232 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7233 "")
8ef30996
MM
7234
7235(define_expand "lshrdi3"
7236 [(parallel [(set (match_operand:DI 0 "register_operand" "")
cafe096b 7237 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8ef30996
MM
7238 (match_operand:SI 2 "arith_operand" "")))
7239 (clobber (match_dup 3))])]
2bcb2ab3 7240 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
7241 "
7242{
7243 if (TARGET_64BIT)
7244 {
2bcb2ab3
GK
7245 /* On the mips16, a shift of more than 8 is a four byte
7246 instruction, so, for a shift between 8 and 16, it is just as
7247 fast to do two shifts of 8 or less. If there is a lot of
7248 shifting going on, we may win in CSE. Otherwise combine will
7249 put the shifts back together again. */
7250 if (TARGET_MIPS16
7251 && optimize
7252 && GET_CODE (operands[2]) == CONST_INT
7253 && INTVAL (operands[2]) > 8
7254 && INTVAL (operands[2]) <= 16)
7255 {
7256 rtx temp = gen_reg_rtx (DImode);
7257
7258 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7259 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7260 GEN_INT (INTVAL (operands[2]) - 8)));
7261 DONE;
7262 }
7263
bb621ad7
JW
7264 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7265 operands[2]));
7266 DONE;
7267 }
7268
7269 operands[3] = gen_reg_rtx (SImode);
7270}")
8ef30996
MM
7271
7272
7273(define_insn "lshrdi3_internal"
7274 [(set (match_operand:DI 0 "register_operand" "=&d")
7275 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7276 (match_operand:SI 2 "register_operand" "d")))
7277 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 7278 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7a38df19 7279 "*
8ef30996
MM
7280{
7281 operands[4] = const0_rtx;
7282 dslots_jump_total += 3;
7283 dslots_jump_filled += 2;
7284
7285 return \"sll\\t%3,%2,26\\n\\
7286\\tbgez\\t%3,1f\\n\\
7287\\tsrl\\t%L0,%M1,%2\\n\\
7288\\t%(b\\t3f\\n\\
7289\\tmove\\t%M0,%z4%)\\n\\
7290\\n\\
efa3896a 7291%~1:\\n\\
8ef30996
MM
7292\\t%(beq\\t%3,%z4,2f\\n\\
7293\\tsrl\\t%L0,%L1,%2%)\\n\\
7294\\n\\
7295\\tsubu\\t%3,%z4,%2\\n\\
7296\\tsll\\t%3,%M1,%3\\n\\
7297\\tor\\t%L0,%L0,%3\\n\\
efa3896a 7298%~2:\\n\\
8ef30996 7299\\tsrl\\t%M0,%M1,%2\\n\\
efa3896a 7300%~3:\";
8ef30996
MM
7301}"
7302 [(set_attr "type" "darith")
7303 (set_attr "mode" "DI")
0ff83799 7304 (set_attr "length" "48")])
8ef30996
MM
7305
7306
7307(define_insn "lshrdi3_internal2"
7308 [(set (match_operand:DI 0 "register_operand" "=d")
7309 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7310 (match_operand:SI 2 "small_int" "IJK")))
7311 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3
GK
7312 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7313 && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
7314 "*
7315{
95936d18 7316 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
7317 operands[4] = const0_rtx;
7318 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7319}"
7320 [(set_attr "type" "darith")
7321 (set_attr "mode" "DI")
0ff83799 7322 (set_attr "length" "8")])
8ef30996
MM
7323
7324
7325(define_split
7326 [(set (match_operand:DI 0 "register_operand" "")
7327 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7328 (match_operand:SI 2 "small_int" "")))
7329 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7330 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7331 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7332 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7333 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7334 && (INTVAL (operands[2]) & 32) != 0"
7335
ddef6bc7
JJ
7336 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7337 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
8ef30996 7338
95936d18 7339 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
7340
7341
7342(define_split
7343 [(set (match_operand:DI 0 "register_operand" "")
7344 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7345 (match_operand:SI 2 "small_int" "")))
7346 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7347 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7348 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7349 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7350 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7351 && (INTVAL (operands[2]) & 32) != 0"
7352
ddef6bc7 7353 [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
8ef30996
MM
7354 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7355
95936d18 7356 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
7357
7358
7359(define_insn "lshrdi3_internal3"
7360 [(set (match_operand:DI 0 "register_operand" "=d")
7361 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7362 (match_operand:SI 2 "small_int" "IJK")))
7363 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 7364 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7365 && (INTVAL (operands[2]) & 63) < 32
7366 && (INTVAL (operands[2]) & 63) != 0"
7367 "*
7368{
7369 int amount = INTVAL (operands[2]);
7370
c5c76735
JL
7371 operands[2] = GEN_INT (amount & 31);
7372 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7373
7374 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7375}"
7376 [(set_attr "type" "darith")
7377 (set_attr "mode" "DI")
0ff83799 7378 (set_attr "length" "16")])
8ef30996
MM
7379
7380
7381(define_split
7382 [(set (match_operand:DI 0 "register_operand" "")
7383 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7384 (match_operand:SI 2 "small_int" "")))
7385 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7386 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7387 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7388 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7389 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7390 && (INTVAL (operands[2]) & 63) < 32
7391 && (INTVAL (operands[2]) & 63) != 0"
7392
7393 [(set (subreg:SI (match_dup 0) 0)
7394 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7395 (match_dup 2)))
7396
7397 (set (match_dup 3)
ddef6bc7 7398 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7399 (match_dup 4)))
7400
7401 (set (subreg:SI (match_dup 0) 0)
7402 (ior:SI (subreg:SI (match_dup 0) 0)
7403 (match_dup 3)))
7404
ddef6bc7
JJ
7405 (set (subreg:SI (match_dup 0) 4)
7406 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7407 (match_dup 2)))]
7408 "
7409{
7410 int amount = INTVAL (operands[2]);
c5c76735
JL
7411 operands[2] = GEN_INT (amount & 31);
7412 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7413}")
7414
7415
7416(define_split
7417 [(set (match_operand:DI 0 "register_operand" "")
7418 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7419 (match_operand:SI 2 "small_int" "")))
7420 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7421 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7422 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7423 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7424 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7425 && (INTVAL (operands[2]) & 63) < 32
7426 && (INTVAL (operands[2]) & 63) != 0"
7427
ddef6bc7
JJ
7428 [(set (subreg:SI (match_dup 0) 4)
7429 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7430 (match_dup 2)))
7431
7432 (set (match_dup 3)
7433 (ashift:SI (subreg:SI (match_dup 1) 0)
7434 (match_dup 4)))
7435
ddef6bc7
JJ
7436 (set (subreg:SI (match_dup 0) 4)
7437 (ior:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
7438 (match_dup 3)))
7439
7440 (set (subreg:SI (match_dup 0) 0)
7441 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7442 (match_dup 2)))]
7443 "
7444{
7445 int amount = INTVAL (operands[2]);
c5c76735
JL
7446 operands[2] = GEN_INT (amount & 31);
7447 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7448}")
7449
bb621ad7
JW
7450
7451(define_insn "lshrdi3_internal4"
7452 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 7453 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 7454 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 7455 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
7456 "*
7457{
7458 if (GET_CODE (operands[2]) == CONST_INT)
7459 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7460
7461 return \"dsrl\\t%0,%1,%2\";
7462}"
7463 [(set_attr "type" "arith")
0ff83799 7464 (set_attr "mode" "DI")])
bb621ad7 7465
2bcb2ab3
GK
7466(define_insn ""
7467 [(set (match_operand:DI 0 "register_operand" "=d,d")
cafe096b 7468 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
2bcb2ab3
GK
7469 (match_operand:SI 2 "arith_operand" "d,I")))]
7470 "TARGET_64BIT && TARGET_MIPS16"
7471 "*
7472{
7473 if (GET_CODE (operands[2]) == CONST_INT)
7474 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7475
7476 return \"dsrl\\t%0,%2\";
7477}"
7478 [(set_attr "type" "arith")
7479 (set_attr "mode" "DI")
7480 (set_attr_alternative "length"
0ff83799 7481 [(const_int 4)
2bcb2ab3 7482 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7483 (const_int 4)
7484 (const_int 8))])])
2bcb2ab3 7485
5ce6f47b
EC
7486(define_insn "rotrsi3"
7487 [(set (match_operand:SI 0 "register_operand" "=d")
7488 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
7489 (match_operand:SI 2 "arith_operand" "dn")))]
7490 "ISA_HAS_ROTR_SI"
7491 "*
7492{
7493 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
7494 return \"rorv\\t%0,%1,%2\";
7495
7496 if ((GET_CODE (operands[2]) == CONST_INT)
7497 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
7498 abort ();
7499
7500 return \"ror\\t%0,%1,%2\";
7501}"
7502 [(set_attr "type" "arith")
7503 (set_attr "mode" "SI")])
7504
7505(define_insn "rotrdi3"
7506 [(set (match_operand:DI 0 "register_operand" "=d")
7507 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
7508 (match_operand:DI 2 "arith_operand" "dn")))]
7509 "ISA_HAS_ROTR_DI"
7510 "*
7511{
7512 if (TARGET_SR71K)
7513 {
7514 if (GET_CODE (operands[2]) != CONST_INT)
7515 return \"drorv\\t%0,%1,%2\";
7516
7517 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
7518 return \"dror32\\t%0,%1,%2\";
7519 }
7520
7521 if ((GET_CODE (operands[2]) == CONST_INT)
7522 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
7523 abort ();
7524
7525 return \"dror\\t%0,%1,%2\";
7526}"
7527 [(set_attr "type" "arith")
7528 (set_attr "mode" "DI")])
7529
7530
2bcb2ab3
GK
7531;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7532
7533(define_split
7534 [(set (match_operand:DI 0 "register_operand" "")
7535 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7536 (match_operand:SI 2 "const_int_operand" "")))]
2ca2d9ee 7537 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
2bcb2ab3
GK
7538 && GET_CODE (operands[2]) == CONST_INT
7539 && INTVAL (operands[2]) > 8
7540 && INTVAL (operands[2]) <= 16"
7541 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7542 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7543"
7544{
7545 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7546}")
7547
8ef30996
MM
7548\f
7549;;
7550;; ....................
7551;;
7552;; COMPARISONS
7553;;
7554;; ....................
7555
7556;; Flow here is rather complex:
7557;;
bb621ad7 7558;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
8ef30996
MM
7559;; arguments into the branch_cmp array, and the type into
7560;; branch_type. No RTL is generated.
7561;;
7562;; 2) The appropriate branch define_expand is called, which then
7563;; creates the appropriate RTL for the comparison and branch.
7564;; Different CC modes are used, based on what type of branch is
7565;; done, so that we can constrain things appropriately. There
7566;; are assumptions in the rest of GCC that break if we fold the
7567;; operands into the branchs for integer operations, and use cc0
34b650b3
MM
7568;; for floating point, so we use the fp status register instead.
7569;; If needed, an appropriate temporary is created to hold the
7570;; of the integer compare.
8ef30996
MM
7571
7572(define_expand "cmpsi"
7573 [(set (cc0)
7574 (compare:CC (match_operand:SI 0 "register_operand" "")
7575 (match_operand:SI 1 "arith_operand" "")))]
7576 ""
7577 "
7578{
7579 if (operands[0]) /* avoid unused code message */
7580 {
7581 branch_cmp[0] = operands[0];
7582 branch_cmp[1] = operands[1];
7583 branch_type = CMP_SI;
7584 DONE;
7585 }
7586}")
7587
7588(define_expand "tstsi"
7589 [(set (cc0)
7590 (match_operand:SI 0 "register_operand" ""))]
7591 ""
7592 "
7593{
7594 if (operands[0]) /* avoid unused code message */
7595 {
7596 branch_cmp[0] = operands[0];
7597 branch_cmp[1] = const0_rtx;
7598 branch_type = CMP_SI;
7599 DONE;
7600 }
7601}")
7602
bb621ad7
JW
7603(define_expand "cmpdi"
7604 [(set (cc0)
cafe096b
EC
7605 (compare:CC (match_operand:DI 0 "register_operand" "")
7606 (match_operand:DI 1 "arith_operand" "")))]
bb621ad7
JW
7607 "TARGET_64BIT"
7608 "
7609{
7610 if (operands[0]) /* avoid unused code message */
7611 {
7612 branch_cmp[0] = operands[0];
7613 branch_cmp[1] = operands[1];
7614 branch_type = CMP_DI;
7615 DONE;
7616 }
7617}")
7618
7619(define_expand "tstdi"
7620 [(set (cc0)
cafe096b 7621 (match_operand:DI 0 "register_operand" ""))]
bb621ad7
JW
7622 "TARGET_64BIT"
7623 "
7624{
7625 if (operands[0]) /* avoid unused code message */
7626 {
7627 branch_cmp[0] = operands[0];
7628 branch_cmp[1] = const0_rtx;
7629 branch_type = CMP_DI;
7630 DONE;
7631 }
7632}")
7633
8ef30996
MM
7634(define_expand "cmpdf"
7635 [(set (cc0)
b8eb88d0
ILT
7636 (compare:CC (match_operand:DF 0 "register_operand" "")
7637 (match_operand:DF 1 "register_operand" "")))]
46299de9 7638 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
7639 "
7640{
7641 if (operands[0]) /* avoid unused code message */
7642 {
7643 branch_cmp[0] = operands[0];
7644 branch_cmp[1] = operands[1];
7645 branch_type = CMP_DF;
7646 DONE;
7647 }
7648}")
7649
8ef30996
MM
7650(define_expand "cmpsf"
7651 [(set (cc0)
b8eb88d0
ILT
7652 (compare:CC (match_operand:SF 0 "register_operand" "")
7653 (match_operand:SF 1 "register_operand" "")))]
8ef30996
MM
7654 "TARGET_HARD_FLOAT"
7655 "
7656{
7657 if (operands[0]) /* avoid unused code message */
7658 {
7659 branch_cmp[0] = operands[0];
7660 branch_cmp[1] = operands[1];
7661 branch_type = CMP_SF;
7662 DONE;
7663 }
7664}")
7665
8ef30996
MM
7666\f
7667;;
7668;; ....................
7669;;
7670;; CONDITIONAL BRANCHES
7671;;
7672;; ....................
7673
0ff83799
MM
7674;; Conditional branches on floating-point equality tests.
7675
7676(define_insn "branch_fp"
8ef30996 7677 [(set (pc)
7a38df19 7678 (if_then_else
0ff83799
MM
7679 (match_operator:CC 0 "cmp_op"
7680 [(match_operand:CC 2 "register_operand" "z")
7681 (const_int 0)])
7682 (label_ref (match_operand 1 "" ""))
7683 (pc)))]
bb621ad7 7684 "TARGET_HARD_FLOAT"
8ef30996
MM
7685 "*
7686{
0ff83799
MM
7687 return mips_output_conditional_branch (insn,
7688 operands,
7689 /*two_operands_p=*/0,
7690 /*float_p=*/1,
7691 /*inverted_p=*/0,
7692 get_attr_length (insn));
8ef30996
MM
7693}"
7694 [(set_attr "type" "branch")
0ff83799 7695 (set_attr "mode" "none")])
8ef30996 7696
0ff83799 7697(define_insn "branch_fp_inverted"
8ef30996 7698 [(set (pc)
7a38df19 7699 (if_then_else
0ff83799
MM
7700 (match_operator:CC 0 "cmp_op"
7701 [(match_operand:CC 2 "register_operand" "z")
7702 (const_int 0)])
7703 (pc)
7704 (label_ref (match_operand 1 "" ""))))]
bb621ad7 7705 "TARGET_HARD_FLOAT"
8ef30996
MM
7706 "*
7707{
0ff83799
MM
7708 return mips_output_conditional_branch (insn,
7709 operands,
7710 /*two_operands_p=*/0,
7711 /*float_p=*/1,
7712 /*inverted_p=*/1,
7713 get_attr_length (insn));
8ef30996
MM
7714}"
7715 [(set_attr "type" "branch")
0ff83799
MM
7716 (set_attr "mode" "none")])
7717
7718;; Conditional branches on comparisons with zero.
8ef30996 7719
34b650b3 7720(define_insn "branch_zero"
8ef30996 7721 [(set (pc)
7a38df19 7722 (if_then_else
0ff83799
MM
7723 (match_operator:SI 0 "cmp_op"
7724 [(match_operand:SI 2 "register_operand" "d")
7725 (const_int 0)])
7726 (label_ref (match_operand 1 "" ""))
7727 (pc)))]
2bcb2ab3 7728 "!TARGET_MIPS16"
8ef30996
MM
7729 "*
7730{
0ff83799
MM
7731 return mips_output_conditional_branch (insn,
7732 operands,
7733 /*two_operands_p=*/0,
7734 /*float_p=*/0,
7735 /*inverted_p=*/0,
7736 get_attr_length (insn));
7737}"
7738 [(set_attr "type" "branch")
7739 (set_attr "mode" "none")])
8ef30996 7740
0ff83799
MM
7741(define_insn "branch_zero_inverted"
7742 [(set (pc)
7a38df19 7743 (if_then_else
0ff83799
MM
7744 (match_operator:SI 0 "cmp_op"
7745 [(match_operand:SI 2 "register_operand" "d")
7746 (const_int 0)])
7747 (pc)
7748 (label_ref (match_operand 1 "" ""))))]
7749 "!TARGET_MIPS16"
7750 "*
7751{
7752 return mips_output_conditional_branch (insn,
7753 operands,
7754 /*two_operands_p=*/0,
7755 /*float_p=*/0,
7756 /*inverted_p=*/1,
7757 get_attr_length (insn));
7758}"
7759 [(set_attr "type" "branch")
7760 (set_attr "mode" "none")])
8ef30996 7761
0ff83799
MM
7762(define_insn "branch_zero_di"
7763 [(set (pc)
7a38df19 7764 (if_then_else
0ff83799 7765 (match_operator:DI 0 "cmp_op"
cafe096b 7766 [(match_operand:DI 2 "register_operand" "d")
0ff83799
MM
7767 (const_int 0)])
7768 (label_ref (match_operand 1 "" ""))
7769 (pc)))]
7770 "!TARGET_MIPS16"
7771 "*
7772{
7773 return mips_output_conditional_branch (insn,
7774 operands,
7775 /*two_operands_p=*/0,
7776 /*float_p=*/0,
7777 /*inverted_p=*/0,
7778 get_attr_length (insn));
8ef30996
MM
7779}"
7780 [(set_attr "type" "branch")
0ff83799
MM
7781 (set_attr "mode" "none")])
7782
7783(define_insn "branch_zero_di_inverted"
7784 [(set (pc)
7a38df19 7785 (if_then_else
0ff83799 7786 (match_operator:DI 0 "cmp_op"
cafe096b 7787 [(match_operand:DI 2 "register_operand" "d")
0ff83799
MM
7788 (const_int 0)])
7789 (pc)
7790 (label_ref (match_operand 1 "" ""))))]
7791 "!TARGET_MIPS16"
7792 "*
7793{
7794 return mips_output_conditional_branch (insn,
7795 operands,
7796 /*two_operands_p=*/0,
7797 /*float_p=*/0,
7798 /*inverted_p=*/1,
7799 get_attr_length (insn));
7800}"
7801 [(set_attr "type" "branch")
7802 (set_attr "mode" "none")])
7803
7804;; Conditional branch on equality comparision.
7805
7806(define_insn "branch_equality"
7807 [(set (pc)
7a38df19 7808 (if_then_else
0ff83799
MM
7809 (match_operator:SI 0 "equality_op"
7810 [(match_operand:SI 2 "register_operand" "d")
7811 (match_operand:SI 3 "register_operand" "d")])
7812 (label_ref (match_operand 1 "" ""))
7813 (pc)))]
7814 "!TARGET_MIPS16"
7815 "*
7816{
7817 return mips_output_conditional_branch (insn,
7818 operands,
7819 /*two_operands_p=*/1,
7820 /*float_p=*/0,
7821 /*inverted_p=*/0,
7822 get_attr_length (insn));
7823}"
7824 [(set_attr "type" "branch")
7825 (set_attr "mode" "none")])
7826
7827(define_insn "branch_equality_di"
7828 [(set (pc)
7a38df19 7829 (if_then_else
0ff83799 7830 (match_operator:DI 0 "equality_op"
cafe096b
EC
7831 [(match_operand:DI 2 "register_operand" "d")
7832 (match_operand:DI 3 "register_operand" "d")])
0ff83799
MM
7833 (label_ref (match_operand 1 "" ""))
7834 (pc)))]
7835 "!TARGET_MIPS16"
7836 "*
7837{
7838 return mips_output_conditional_branch (insn,
7839 operands,
7840 /*two_operands_p=*/1,
7841 /*float_p=*/0,
7842 /*inverted_p=*/0,
7843 get_attr_length (insn));
7844}"
7845 [(set_attr "type" "branch")
7846 (set_attr "mode" "none")])
7847
7848(define_insn "branch_equality_inverted"
7849 [(set (pc)
7a38df19 7850 (if_then_else
0ff83799
MM
7851 (match_operator:SI 0 "equality_op"
7852 [(match_operand:SI 2 "register_operand" "d")
7853 (match_operand:SI 3 "register_operand" "d")])
7854 (pc)
7855 (label_ref (match_operand 1 "" ""))))]
7856 "!TARGET_MIPS16"
7857 "*
7858{
7859 return mips_output_conditional_branch (insn,
7860 operands,
7861 /*two_operands_p=*/1,
7862 /*float_p=*/0,
7863 /*inverted_p=*/1,
7864 get_attr_length (insn));
7865}"
7866 [(set_attr "type" "branch")
7867 (set_attr "mode" "none")])
7868
7869(define_insn "branch_equality_di_inverted"
7870 [(set (pc)
7a38df19 7871 (if_then_else
0ff83799 7872 (match_operator:DI 0 "equality_op"
cafe096b
EC
7873 [(match_operand:DI 2 "register_operand" "d")
7874 (match_operand:DI 3 "register_operand" "d")])
0ff83799
MM
7875 (pc)
7876 (label_ref (match_operand 1 "" ""))))]
7877 "!TARGET_MIPS16"
7878 "*
7879{
7880 return mips_output_conditional_branch (insn,
7881 operands,
7882 /*two_operands_p=*/1,
7883 /*float_p=*/0,
7884 /*inverted_p=*/1,
7885 get_attr_length (insn));
7886}"
7887 [(set_attr "type" "branch")
7888 (set_attr "mode" "none")])
8ef30996 7889
0ff83799 7890;; MIPS16 branches
8ef30996 7891
2bcb2ab3
GK
7892(define_insn ""
7893 [(set (pc)
7894 (if_then_else (match_operator:SI 0 "equality_op"
7895 [(match_operand:SI 1 "register_operand" "d,t")
7896 (const_int 0)])
7897 (match_operand 2 "pc_or_label_operand" "")
7898 (match_operand 3 "pc_or_label_operand" "")))]
7899 "TARGET_MIPS16"
7900 "*
7901{
7902 if (operands[2] != pc_rtx)
7903 {
7904 if (which_alternative == 0)
7905 return \"%*b%C0z\\t%1,%2\";
7906 else
7907 return \"%*bt%C0z\\t%2\";
7908 }
7909 else
7910 {
7911 if (which_alternative == 0)
7912 return \"%*b%N0z\\t%1,%3\";
7913 else
7914 return \"%*bt%N0z\\t%3\";
7915 }
7916}"
7917 [(set_attr "type" "branch")
7918 (set_attr "mode" "none")
0ff83799 7919 (set_attr "length" "8")])
bb621ad7 7920
2bcb2ab3
GK
7921(define_insn ""
7922 [(set (pc)
7923 (if_then_else (match_operator:DI 0 "equality_op"
cafe096b 7924 [(match_operand:DI 1 "register_operand" "d,t")
2bcb2ab3
GK
7925 (const_int 0)])
7926 (match_operand 2 "pc_or_label_operand" "")
7927 (match_operand 3 "pc_or_label_operand" "")))]
7928 "TARGET_MIPS16"
7929 "*
7930{
7931 if (operands[2] != pc_rtx)
7932 {
7933 if (which_alternative == 0)
7934 return \"%*b%C0z\\t%1,%2\";
7935 else
7936 return \"%*bt%C0z\\t%2\";
7937 }
7938 else
7939 {
7940 if (which_alternative == 0)
7941 return \"%*b%N0z\\t%1,%3\";
7942 else
7943 return \"%*bt%N0z\\t%3\";
7944 }
7945}"
7946 [(set_attr "type" "branch")
7947 (set_attr "mode" "none")
0ff83799 7948 (set_attr "length" "8")])
bb621ad7 7949
ce3649d2
EC
7950(define_expand "bunordered"
7951 [(set (pc)
7952 (if_then_else (unordered:CC (cc0)
7953 (const_int 0))
7954 (label_ref (match_operand 0 "" ""))
7955 (pc)))]
7956 ""
7957 "
7958{
7959 if (operands[0]) /* avoid unused code warning */
7960 {
7961 gen_conditional_branch (operands, UNORDERED);
7962 DONE;
7963 }
7964}")
7965
7966(define_expand "bordered"
7967 [(set (pc)
7968 (if_then_else (ordered:CC (cc0)
7969 (const_int 0))
7970 (label_ref (match_operand 0 "" ""))
7971 (pc)))]
7972 ""
7973 "
7974{
7975 if (operands[0]) /* avoid unused code warning */
7976 {
7977 gen_conditional_branch (operands, ORDERED);
7978 DONE;
7979 }
7980}")
7981
ce3649d2
EC
7982(define_expand "bunlt"
7983 [(set (pc)
7984 (if_then_else (unlt:CC (cc0)
7985 (const_int 0))
7986 (label_ref (match_operand 0 "" ""))
7987 (pc)))]
7988 ""
7989 "
7990{
7991 if (operands[0]) /* avoid unused code warning */
7992 {
7993 gen_conditional_branch (operands, UNLT);
7994 DONE;
7995 }
7996}")
7997
8ab907e8
RS
7998(define_expand "bunge"
7999 [(set (pc)
8000 (if_then_else (unge:CC (cc0)
8001 (const_int 0))
8002 (label_ref (match_operand 0 "" ""))
8003 (pc)))]
8004 ""
8005 "
8006{
8007 gen_conditional_branch (operands, UNGE);
8008 DONE;
8009}")
8010
ce3649d2
EC
8011(define_expand "buneq"
8012 [(set (pc)
8013 (if_then_else (uneq:CC (cc0)
8014 (const_int 0))
8015 (label_ref (match_operand 0 "" ""))
8016 (pc)))]
8017 ""
8018 "
8019{
8020 if (operands[0]) /* avoid unused code warning */
8021 {
8022 gen_conditional_branch (operands, UNEQ);
8023 DONE;
8024 }
8025}")
8026
8ab907e8
RS
8027(define_expand "bltgt"
8028 [(set (pc)
8029 (if_then_else (ltgt:CC (cc0)
8030 (const_int 0))
8031 (label_ref (match_operand 0 "" ""))
8032 (pc)))]
8033 ""
8034 "
8035{
8036 gen_conditional_branch (operands, LTGT);
8037 DONE;
8038}")
8039
ce3649d2
EC
8040(define_expand "bunle"
8041 [(set (pc)
8042 (if_then_else (unle:CC (cc0)
8043 (const_int 0))
8044 (label_ref (match_operand 0 "" ""))
8045 (pc)))]
8046 ""
8047 "
8048{
8049 if (operands[0]) /* avoid unused code warning */
8050 {
8051 gen_conditional_branch (operands, UNLE);
8052 DONE;
8053 }
8054}")
8055
8ab907e8
RS
8056(define_expand "bungt"
8057 [(set (pc)
8058 (if_then_else (ungt:CC (cc0)
8059 (const_int 0))
8060 (label_ref (match_operand 0 "" ""))
8061 (pc)))]
8062 ""
8063 "
8064{
8065 gen_conditional_branch (operands, UNGT);
8066 DONE;
8067}")
8068
8ef30996
MM
8069(define_expand "beq"
8070 [(set (pc)
b8eb88d0
ILT
8071 (if_then_else (eq:CC (cc0)
8072 (const_int 0))
8ef30996
MM
8073 (label_ref (match_operand 0 "" ""))
8074 (pc)))]
8075 ""
8076 "
8077{
8078 if (operands[0]) /* avoid unused code warning */
8079 {
8080 gen_conditional_branch (operands, EQ);
8081 DONE;
8082 }
8083}")
8084
8085(define_expand "bne"
8086 [(set (pc)
b8eb88d0
ILT
8087 (if_then_else (ne:CC (cc0)
8088 (const_int 0))
8ef30996
MM
8089 (label_ref (match_operand 0 "" ""))
8090 (pc)))]
8091 ""
8092 "
8093{
8094 if (operands[0]) /* avoid unused code warning */
8095 {
8096 gen_conditional_branch (operands, NE);
8097 DONE;
8098 }
8099}")
8100
8101(define_expand "bgt"
8102 [(set (pc)
8103 (if_then_else (gt:CC (cc0)
8104 (const_int 0))
8105 (label_ref (match_operand 0 "" ""))
8106 (pc)))]
8107 ""
8108 "
8109{
8110 if (operands[0]) /* avoid unused code warning */
8111 {
8112 gen_conditional_branch (operands, GT);
8113 DONE;
8114 }
8115}")
8116
8117(define_expand "bge"
8118 [(set (pc)
8119 (if_then_else (ge:CC (cc0)
8120 (const_int 0))
8121 (label_ref (match_operand 0 "" ""))
8122 (pc)))]
8123 ""
8124 "
8125{
8126 if (operands[0]) /* avoid unused code warning */
8127 {
8128 gen_conditional_branch (operands, GE);
8129 DONE;
8130 }
8131}")
8132
8133(define_expand "blt"
8134 [(set (pc)
8135 (if_then_else (lt:CC (cc0)
8136 (const_int 0))
8137 (label_ref (match_operand 0 "" ""))
8138 (pc)))]
8139 ""
8140 "
8141{
8142 if (operands[0]) /* avoid unused code warning */
8143 {
8144 gen_conditional_branch (operands, LT);
8145 DONE;
8146 }
8147}")
8148
8149(define_expand "ble"
8150 [(set (pc)
8151 (if_then_else (le:CC (cc0)
8152 (const_int 0))
8153 (label_ref (match_operand 0 "" ""))
8154 (pc)))]
8155 ""
8156 "
8157{
8158 if (operands[0]) /* avoid unused code warning */
8159 {
8160 gen_conditional_branch (operands, LE);
8161 DONE;
8162 }
8163}")
8164
8165(define_expand "bgtu"
8166 [(set (pc)
8167 (if_then_else (gtu:CC (cc0)
8168 (const_int 0))
8169 (label_ref (match_operand 0 "" ""))
8170 (pc)))]
8171 ""
8172 "
8173{
8174 if (operands[0]) /* avoid unused code warning */
8175 {
8176 gen_conditional_branch (operands, GTU);
8177 DONE;
8178 }
8179}")
8180
8181(define_expand "bgeu"
8182 [(set (pc)
8183 (if_then_else (geu:CC (cc0)
8184 (const_int 0))
8185 (label_ref (match_operand 0 "" ""))
8186 (pc)))]
8187 ""
8188 "
8189{
8190 if (operands[0]) /* avoid unused code warning */
8191 {
8192 gen_conditional_branch (operands, GEU);
8193 DONE;
8194 }
8195}")
8196
8197
8198(define_expand "bltu"
8199 [(set (pc)
8200 (if_then_else (ltu:CC (cc0)
8201 (const_int 0))
8202 (label_ref (match_operand 0 "" ""))
8203 (pc)))]
8204 ""
8205 "
8206{
8207 if (operands[0]) /* avoid unused code warning */
8208 {
8209 gen_conditional_branch (operands, LTU);
8210 DONE;
8211 }
8212}")
8213
8214(define_expand "bleu"
8215 [(set (pc)
8216 (if_then_else (leu:CC (cc0)
8217 (const_int 0))
8218 (label_ref (match_operand 0 "" ""))
8219 (pc)))]
8220 ""
8221 "
8222{
8223 if (operands[0]) /* avoid unused code warning */
8224 {
8225 gen_conditional_branch (operands, LEU);
8226 DONE;
8227 }
8228}")
8229
8230\f
8231;;
8232;; ....................
8233;;
8234;; SETTING A REGISTER FROM A COMPARISON
8235;;
8236;; ....................
8237
8238(define_expand "seq"
8239 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3
MM
8240 (eq:SI (match_dup 1)
8241 (match_dup 2)))]
8ef30996
MM
8242 ""
8243 "
8244{
bb621ad7 8245 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8246 FAIL;
8247
8248 /* set up operands from compare. */
8249 operands[1] = branch_cmp[0];
8250 operands[2] = branch_cmp[1];
8251
2bcb2ab3 8252 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8253 {
8254 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8255 DONE;
8256 }
8257
8ef30996
MM
8258 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8259 operands[2] = force_reg (SImode, operands[2]);
8260
8261 /* fall through and generate default code */
8262}")
8263
34b650b3
MM
8264
8265(define_insn "seq_si_zero"
8266 [(set (match_operand:SI 0 "register_operand" "=d")
8267 (eq:SI (match_operand:SI 1 "register_operand" "d")
8268 (const_int 0)))]
2bcb2ab3 8269 "!TARGET_MIPS16"
34b650b3 8270 "sltu\\t%0,%1,1"
bb621ad7 8271 [(set_attr "type" "arith")
0ff83799 8272 (set_attr "mode" "SI")])
34b650b3 8273
2bcb2ab3
GK
8274(define_insn ""
8275 [(set (match_operand:SI 0 "register_operand" "=t")
8276 (eq:SI (match_operand:SI 1 "register_operand" "d")
8277 (const_int 0)))]
8278 "TARGET_MIPS16"
8279 "sltu\\t%1,1"
8280 [(set_attr "type" "arith")
0ff83799 8281 (set_attr "mode" "SI")])
2bcb2ab3 8282
bb621ad7
JW
8283(define_insn "seq_di_zero"
8284 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 8285 (eq:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 8286 (const_int 0)))]
2bcb2ab3 8287 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8288 "sltu\\t%0,%1,1"
8289 [(set_attr "type" "arith")
0ff83799 8290 (set_attr "mode" "DI")])
bb621ad7 8291
2bcb2ab3
GK
8292(define_insn ""
8293 [(set (match_operand:DI 0 "register_operand" "=t")
cafe096b 8294 (eq:DI (match_operand:DI 1 "register_operand" "d")
2bcb2ab3
GK
8295 (const_int 0)))]
8296 "TARGET_64BIT && TARGET_MIPS16"
8297 "sltu\\t%1,1"
8298 [(set_attr "type" "arith")
0ff83799 8299 (set_attr "mode" "DI")])
2bcb2ab3 8300
34b650b3
MM
8301(define_insn "seq_si"
8302 [(set (match_operand:SI 0 "register_operand" "=d,d")
8303 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8304 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 8305 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8ef30996 8306 "@
8ef30996 8307 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
34b650b3 8308 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
bb621ad7
JW
8309 [(set_attr "type" "arith")
8310 (set_attr "mode" "SI")
0ff83799 8311 (set_attr "length" "8")])
bb621ad7
JW
8312
8313(define_split
8314 [(set (match_operand:SI 0 "register_operand" "")
8315 (eq:SI (match_operand:SI 1 "register_operand" "")
8316 (match_operand:SI 2 "uns_arith_operand" "")))]
2bcb2ab3 8317 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
bb621ad7
JW
8318 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8319 [(set (match_dup 0)
8320 (xor:SI (match_dup 1)
8321 (match_dup 2)))
8322 (set (match_dup 0)
8323 (ltu:SI (match_dup 0)
8324 (const_int 1)))]
8325 "")
8326
8327(define_insn "seq_di"
8328 [(set (match_operand:DI 0 "register_operand" "=d,d")
cafe096b
EC
8329 (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
8330 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 8331 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8332 "@
8333 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8334 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8335 [(set_attr "type" "arith")
8336 (set_attr "mode" "DI")
0ff83799 8337 (set_attr "length" "8")])
8ef30996
MM
8338
8339(define_split
bb621ad7 8340 [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
8341 (eq:DI (match_operand:DI 1 "register_operand" "")
8342 (match_operand:DI 2 "uns_arith_operand" "")))]
bb621ad7 8343 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
2bcb2ab3 8344 && !TARGET_MIPS16
26b8e6e5 8345 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8ef30996 8346 [(set (match_dup 0)
bb621ad7 8347 (xor:DI (match_dup 1)
8ef30996
MM
8348 (match_dup 2)))
8349 (set (match_dup 0)
bb621ad7 8350 (ltu:DI (match_dup 0)
8ef30996
MM
8351 (const_int 1)))]
8352 "")
8353
2bcb2ab3
GK
8354;; On the mips16 the default code is better than using sltu.
8355
8ef30996
MM
8356(define_expand "sne"
8357 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3
MM
8358 (ne:SI (match_dup 1)
8359 (match_dup 2)))]
2bcb2ab3 8360 "!TARGET_MIPS16"
8ef30996
MM
8361 "
8362{
bb621ad7 8363 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8364 FAIL;
8365
8366 /* set up operands from compare. */
8367 operands[1] = branch_cmp[0];
8368 operands[2] = branch_cmp[1];
8369
bb621ad7 8370 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
8371 {
8372 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8373 DONE;
8374 }
8375
8ef30996
MM
8376 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8377 operands[2] = force_reg (SImode, operands[2]);
8378
8379 /* fall through and generate default code */
8380}")
8381
34b650b3
MM
8382(define_insn "sne_si_zero"
8383 [(set (match_operand:SI 0 "register_operand" "=d")
8384 (ne:SI (match_operand:SI 1 "register_operand" "d")
8385 (const_int 0)))]
2bcb2ab3 8386 "!TARGET_MIPS16"
34b650b3 8387 "sltu\\t%0,%.,%1"
bb621ad7 8388 [(set_attr "type" "arith")
0ff83799 8389 (set_attr "mode" "SI")])
8ef30996 8390
bb621ad7
JW
8391(define_insn "sne_di_zero"
8392 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 8393 (ne:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 8394 (const_int 0)))]
2bcb2ab3 8395 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8396 "sltu\\t%0,%.,%1"
8397 [(set_attr "type" "arith")
0ff83799 8398 (set_attr "mode" "DI")])
bb621ad7 8399
34b650b3
MM
8400(define_insn "sne_si"
8401 [(set (match_operand:SI 0 "register_operand" "=d,d")
8402 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8403 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 8404 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
34b650b3
MM
8405 "@
8406 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8407 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
bb621ad7 8408 [(set_attr "type" "arith")
92b4cee1 8409 (set_attr "mode" "SI")
0ff83799 8410 (set_attr "length" "8")])
8ef30996
MM
8411
8412(define_split
8413 [(set (match_operand:SI 0 "register_operand" "")
34b650b3
MM
8414 (ne:SI (match_operand:SI 1 "register_operand" "")
8415 (match_operand:SI 2 "uns_arith_operand" "")))]
2bcb2ab3 8416 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
26b8e6e5 8417 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8ef30996
MM
8418 [(set (match_dup 0)
8419 (xor:SI (match_dup 1)
8420 (match_dup 2)))
8421 (set (match_dup 0)
34b650b3 8422 (gtu:SI (match_dup 0)
8ef30996
MM
8423 (const_int 0)))]
8424 "")
8425
bb621ad7
JW
8426(define_insn "sne_di"
8427 [(set (match_operand:DI 0 "register_operand" "=d,d")
cafe096b
EC
8428 (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
8429 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 8430 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8431 "@
8432 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8433 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8434 [(set_attr "type" "arith")
8435 (set_attr "mode" "DI")
0ff83799 8436 (set_attr "length" "8")])
bb621ad7
JW
8437
8438(define_split
8439 [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
8440 (ne:DI (match_operand:DI 1 "register_operand" "")
8441 (match_operand:DI 2 "uns_arith_operand" "")))]
bb621ad7 8442 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
2bcb2ab3 8443 && !TARGET_MIPS16
bb621ad7
JW
8444 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8445 [(set (match_dup 0)
8446 (xor:DI (match_dup 1)
8447 (match_dup 2)))
8448 (set (match_dup 0)
8449 (gtu:DI (match_dup 0)
8450 (const_int 0)))]
8451 "")
8452
8ef30996
MM
8453(define_expand "sgt"
8454 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8455 (gt:SI (match_dup 1)
8ef30996
MM
8456 (match_dup 2)))]
8457 ""
8458 "
8459{
bb621ad7 8460 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8461 FAIL;
8462
8463 /* set up operands from compare. */
8464 operands[1] = branch_cmp[0];
8465 operands[2] = branch_cmp[1];
8466
2bcb2ab3 8467 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8468 {
8469 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8470 DONE;
8471 }
8472
8ef30996
MM
8473 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8474 operands[2] = force_reg (SImode, operands[2]);
8475
8476 /* fall through and generate default code */
8477}")
8478
8479(define_insn "sgt_si"
8480 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8481 (gt:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8482 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
2bcb2ab3 8483 "!TARGET_MIPS16"
8ef30996 8484 "slt\\t%0,%z2,%1"
bb621ad7 8485 [(set_attr "type" "arith")
0ff83799 8486 (set_attr "mode" "SI")])
8ef30996 8487
2bcb2ab3
GK
8488(define_insn ""
8489 [(set (match_operand:SI 0 "register_operand" "=t")
8490 (gt:SI (match_operand:SI 1 "register_operand" "d")
8491 (match_operand:SI 2 "register_operand" "d")))]
8492 "TARGET_MIPS16"
8493 "slt\\t%2,%1"
8494 [(set_attr "type" "arith")
0ff83799 8495 (set_attr "mode" "SI")])
2bcb2ab3 8496
bb621ad7
JW
8497(define_insn "sgt_di"
8498 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8499 (gt:DI (match_operand:DI 1 "register_operand" "d")
8500 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
2bcb2ab3 8501 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8502 "slt\\t%0,%z2,%1"
8503 [(set_attr "type" "arith")
0ff83799 8504 (set_attr "mode" "DI")])
bb621ad7 8505
2bcb2ab3
GK
8506(define_insn ""
8507 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8508 (gt:DI (match_operand:DI 1 "register_operand" "d")
8509 (match_operand:DI 2 "register_operand" "d")))]
2bcb2ab3
GK
8510 "TARGET_64BIT && TARGET_MIPS16"
8511 "slt\\t%2,%1"
8512 [(set_attr "type" "arith")
0ff83799 8513 (set_attr "mode" "DI")])
2bcb2ab3 8514
8ef30996
MM
8515(define_expand "sge"
8516 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8517 (ge:SI (match_dup 1)
8ef30996
MM
8518 (match_dup 2)))]
8519 ""
8520 "
8521{
bb621ad7 8522 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8523 FAIL;
8524
8525 /* set up operands from compare. */
8526 operands[1] = branch_cmp[0];
8527 operands[2] = branch_cmp[1];
8528
2bcb2ab3 8529 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8530 {
8531 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8532 DONE;
8533 }
8534
8ef30996
MM
8535 /* fall through and generate default code */
8536}")
8537
8538(define_insn "sge_si"
8539 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8540 (ge:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8541 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8542 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8ef30996 8543 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
bb621ad7 8544 [(set_attr "type" "arith")
8ef30996 8545 (set_attr "mode" "SI")
0ff83799 8546 (set_attr "length" "8")])
8ef30996
MM
8547
8548(define_split
8549 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8550 (ge:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8551 (match_operand:SI 2 "arith_operand" "")))]
2bcb2ab3 8552 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8553 [(set (match_dup 0)
34b650b3 8554 (lt:SI (match_dup 1)
8ef30996
MM
8555 (match_dup 2)))
8556 (set (match_dup 0)
8557 (xor:SI (match_dup 0)
8558 (const_int 1)))]
8559 "")
8560
bb621ad7
JW
8561(define_insn "sge_di"
8562 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8563 (ge:DI (match_operand:DI 1 "register_operand" "d")
8564 (match_operand:DI 2 "arith_operand" "dI")))]
2bcb2ab3 8565 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8566 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8567 [(set_attr "type" "arith")
8568 (set_attr "mode" "DI")
0ff83799 8569 (set_attr "length" "8")])
bb621ad7
JW
8570
8571(define_split
8572 [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
8573 (ge:DI (match_operand:DI 1 "register_operand" "")
8574 (match_operand:DI 2 "arith_operand" "")))]
2bcb2ab3
GK
8575 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8576 && !TARGET_MIPS16"
bb621ad7
JW
8577 [(set (match_dup 0)
8578 (lt:DI (match_dup 1)
8579 (match_dup 2)))
8580 (set (match_dup 0)
8581 (xor:DI (match_dup 0)
8582 (const_int 1)))]
8583 "")
8584
8ef30996
MM
8585(define_expand "slt"
8586 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8587 (lt:SI (match_dup 1)
8ef30996
MM
8588 (match_dup 2)))]
8589 ""
8590 "
8591{
bb621ad7 8592 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8593 FAIL;
8594
8595 /* set up operands from compare. */
8596 operands[1] = branch_cmp[0];
8597 operands[2] = branch_cmp[1];
8598
2bcb2ab3 8599 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8600 {
8601 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8602 DONE;
8603 }
8604
8ef30996
MM
8605 /* fall through and generate default code */
8606}")
8607
8608(define_insn "slt_si"
8609 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8610 (lt:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8611 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8612 "!TARGET_MIPS16"
8ef30996 8613 "slt\\t%0,%1,%2"
bb621ad7 8614 [(set_attr "type" "arith")
0ff83799 8615 (set_attr "mode" "SI")])
8ef30996 8616
2bcb2ab3
GK
8617(define_insn ""
8618 [(set (match_operand:SI 0 "register_operand" "=t,t")
8619 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8620 (match_operand:SI 2 "arith_operand" "d,I")))]
8621 "TARGET_MIPS16"
8622 "slt\\t%1,%2"
8623 [(set_attr "type" "arith")
8624 (set_attr "mode" "SI")
8625 (set_attr_alternative "length"
0ff83799 8626 [(const_int 4)
2bcb2ab3 8627 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8628 (const_int 4)
8629 (const_int 8))])])
2bcb2ab3 8630
bb621ad7
JW
8631(define_insn "slt_di"
8632 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8633 (lt:DI (match_operand:DI 1 "register_operand" "d")
8634 (match_operand:DI 2 "arith_operand" "dI")))]
2bcb2ab3 8635 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8636 "slt\\t%0,%1,%2"
8637 [(set_attr "type" "arith")
0ff83799 8638 (set_attr "mode" "DI")])
bb621ad7 8639
2bcb2ab3
GK
8640(define_insn ""
8641 [(set (match_operand:DI 0 "register_operand" "=t,t")
cafe096b
EC
8642 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
8643 (match_operand:DI 2 "arith_operand" "d,I")))]
2bcb2ab3
GK
8644 "TARGET_64BIT && TARGET_MIPS16"
8645 "slt\\t%1,%2"
8646 [(set_attr "type" "arith")
8647 (set_attr "mode" "DI")
8648 (set_attr_alternative "length"
0ff83799 8649 [(const_int 4)
2bcb2ab3 8650 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8651 (const_int 4)
8652 (const_int 8))])])
2bcb2ab3 8653
8ef30996
MM
8654(define_expand "sle"
8655 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8656 (le:SI (match_dup 1)
8ef30996
MM
8657 (match_dup 2)))]
8658 ""
8659 "
8660{
bb621ad7 8661 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8662 FAIL;
8663
8664 /* set up operands from compare. */
8665 operands[1] = branch_cmp[0];
8666 operands[2] = branch_cmp[1];
8667
2bcb2ab3 8668 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8669 {
8670 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8671 DONE;
8672 }
8673
8ef30996
MM
8674 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8675 operands[2] = force_reg (SImode, operands[2]);
8676
8677 /* fall through and generate default code */
8678}")
8679
34b650b3
MM
8680(define_insn "sle_si_const"
8681 [(set (match_operand:SI 0 "register_operand" "=d")
8682 (le:SI (match_operand:SI 1 "register_operand" "d")
8683 (match_operand:SI 2 "small_int" "I")))]
2bcb2ab3 8684 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
34b650b3
MM
8685 "*
8686{
95936d18 8687 operands[2] = GEN_INT (INTVAL (operands[2])+1);
34b650b3
MM
8688 return \"slt\\t%0,%1,%2\";
8689}"
bb621ad7 8690 [(set_attr "type" "arith")
0ff83799 8691 (set_attr "mode" "SI")])
34b650b3 8692
2bcb2ab3
GK
8693(define_insn ""
8694 [(set (match_operand:SI 0 "register_operand" "=t")
8695 (le:SI (match_operand:SI 1 "register_operand" "d")
8696 (match_operand:SI 2 "small_int" "I")))]
8697 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8698 "*
8699{
95936d18 8700 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
8701 return \"slt\\t%1,%2\";
8702}"
8703 [(set_attr "type" "arith")
8704 (set_attr "mode" "SI")
8705 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
8706 (const_int 4)
8707 (const_int 8)))])
2bcb2ab3 8708
bb621ad7
JW
8709(define_insn "sle_di_const"
8710 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 8711 (le:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 8712 (match_operand:DI 2 "small_int" "I")))]
2bcb2ab3 8713 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
bb621ad7
JW
8714 "*
8715{
95936d18 8716 operands[2] = GEN_INT (INTVAL (operands[2])+1);
bb621ad7
JW
8717 return \"slt\\t%0,%1,%2\";
8718}"
8719 [(set_attr "type" "arith")
0ff83799 8720 (set_attr "mode" "DI")])
bb621ad7 8721
2bcb2ab3
GK
8722(define_insn ""
8723 [(set (match_operand:DI 0 "register_operand" "=t")
cafe096b 8724 (le:DI (match_operand:DI 1 "register_operand" "d")
2bcb2ab3
GK
8725 (match_operand:DI 2 "small_int" "I")))]
8726 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8727 "*
8728{
95936d18 8729 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
8730 return \"slt\\t%1,%2\";
8731}"
8732 [(set_attr "type" "arith")
8733 (set_attr "mode" "DI")
8734 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
8735 (const_int 4)
8736 (const_int 8)))])
2bcb2ab3 8737
34b650b3
MM
8738(define_insn "sle_si_reg"
8739 [(set (match_operand:SI 0 "register_operand" "=d")
8740 (le:SI (match_operand:SI 1 "register_operand" "d")
8741 (match_operand:SI 2 "register_operand" "d")))]
2bcb2ab3 8742 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
34b650b3 8743 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
bb621ad7 8744 [(set_attr "type" "arith")
34b650b3 8745 (set_attr "mode" "SI")
0ff83799 8746 (set_attr "length" "8")])
8ef30996
MM
8747
8748(define_split
8749 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8750 (le:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8751 (match_operand:SI 2 "register_operand" "")))]
2bcb2ab3 8752 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8753 [(set (match_dup 0)
34b650b3 8754 (lt:SI (match_dup 2)
8ef30996
MM
8755 (match_dup 1)))
8756 (set (match_dup 0)
8757 (xor:SI (match_dup 0)
8758 (const_int 1)))]
8759 "")
8760
bb621ad7
JW
8761(define_insn "sle_di_reg"
8762 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8763 (le:DI (match_operand:DI 1 "register_operand" "d")
8764 (match_operand:DI 2 "register_operand" "d")))]
2bcb2ab3 8765 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8766 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8767 [(set_attr "type" "arith")
8768 (set_attr "mode" "DI")
0ff83799 8769 (set_attr "length" "8")])
bb621ad7
JW
8770
8771(define_split
8772 [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
8773 (le:DI (match_operand:DI 1 "register_operand" "")
8774 (match_operand:DI 2 "register_operand" "")))]
2bcb2ab3
GK
8775 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8776 && !TARGET_MIPS16"
bb621ad7
JW
8777 [(set (match_dup 0)
8778 (lt:DI (match_dup 2)
8779 (match_dup 1)))
8780 (set (match_dup 0)
8781 (xor:DI (match_dup 0)
8782 (const_int 1)))]
8783 "")
8784
8ef30996
MM
8785(define_expand "sgtu"
8786 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8787 (gtu:SI (match_dup 1)
8ef30996
MM
8788 (match_dup 2)))]
8789 ""
8790 "
8791{
bb621ad7 8792 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8793 FAIL;
8794
8795 /* set up operands from compare. */
8796 operands[1] = branch_cmp[0];
8797 operands[2] = branch_cmp[1];
8798
2bcb2ab3 8799 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8800 {
8801 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8802 DONE;
8803 }
8804
8ef30996
MM
8805 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8806 operands[2] = force_reg (SImode, operands[2]);
8807
8808 /* fall through and generate default code */
8809}")
8810
8811(define_insn "sgtu_si"
8812 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8813 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8814 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
479f2cea 8815 "!TARGET_MIPS16"
8ef30996 8816 "sltu\\t%0,%z2,%1"
bb621ad7 8817 [(set_attr "type" "arith")
0ff83799 8818 (set_attr "mode" "SI")])
8ef30996 8819
2bcb2ab3
GK
8820(define_insn ""
8821 [(set (match_operand:SI 0 "register_operand" "=t")
8822 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8823 (match_operand:SI 2 "register_operand" "d")))]
479f2cea 8824 "TARGET_MIPS16"
2bcb2ab3
GK
8825 "sltu\\t%2,%1"
8826 [(set_attr "type" "arith")
0ff83799 8827 (set_attr "mode" "SI")])
2bcb2ab3 8828
bb621ad7
JW
8829(define_insn "sgtu_di"
8830 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8831 (gtu:DI (match_operand:DI 1 "register_operand" "d")
8832 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
479f2cea 8833 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8834 "sltu\\t%0,%z2,%1"
8835 [(set_attr "type" "arith")
0ff83799 8836 (set_attr "mode" "DI")])
bb621ad7 8837
2bcb2ab3
GK
8838(define_insn ""
8839 [(set (match_operand:DI 0 "register_operand" "=t")
cafe096b
EC
8840 (gtu:DI (match_operand:DI 1 "register_operand" "d")
8841 (match_operand:DI 2 "register_operand" "d")))]
479f2cea 8842 "TARGET_64BIT && TARGET_MIPS16"
2bcb2ab3
GK
8843 "sltu\\t%2,%1"
8844 [(set_attr "type" "arith")
0ff83799 8845 (set_attr "mode" "DI")])
2bcb2ab3 8846
8ef30996
MM
8847(define_expand "sgeu"
8848 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8849 (geu:SI (match_dup 1)
8ef30996
MM
8850 (match_dup 2)))]
8851 ""
8852 "
8853{
bb621ad7 8854 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8855 FAIL;
8856
8857 /* set up operands from compare. */
8858 operands[1] = branch_cmp[0];
8859 operands[2] = branch_cmp[1];
8860
2bcb2ab3 8861 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8862 {
8863 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8864 DONE;
8865 }
8866
8ef30996
MM
8867 /* fall through and generate default code */
8868}")
8869
8870(define_insn "sgeu_si"
8871 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8872 (geu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8873 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8874 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8ef30996 8875 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
bb621ad7 8876 [(set_attr "type" "arith")
8ef30996 8877 (set_attr "mode" "SI")
0ff83799 8878 (set_attr "length" "8")])
8ef30996
MM
8879
8880(define_split
8881 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8882 (geu:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8883 (match_operand:SI 2 "arith_operand" "")))]
2bcb2ab3 8884 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8885 [(set (match_dup 0)
34b650b3 8886 (ltu:SI (match_dup 1)
8ef30996
MM
8887 (match_dup 2)))
8888 (set (match_dup 0)
8889 (xor:SI (match_dup 0)
8890 (const_int 1)))]
8891 "")
8892
bb621ad7
JW
8893(define_insn "sgeu_di"
8894 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8895 (geu:DI (match_operand:DI 1 "register_operand" "d")
8896 (match_operand:DI 2 "arith_operand" "dI")))]
2bcb2ab3 8897 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8898 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8899 [(set_attr "type" "arith")
8900 (set_attr "mode" "DI")
0ff83799 8901 (set_attr "length" "8")])
bb621ad7
JW
8902
8903(define_split
8904 [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
8905 (geu:DI (match_operand:DI 1 "register_operand" "")
8906 (match_operand:DI 2 "arith_operand" "")))]
2bcb2ab3
GK
8907 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8908 && !TARGET_MIPS16"
bb621ad7
JW
8909 [(set (match_dup 0)
8910 (ltu:DI (match_dup 1)
8911 (match_dup 2)))
8912 (set (match_dup 0)
8913 (xor:DI (match_dup 0)
8914 (const_int 1)))]
8915 "")
8916
8ef30996
MM
8917(define_expand "sltu"
8918 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8919 (ltu:SI (match_dup 1)
8ef30996
MM
8920 (match_dup 2)))]
8921 ""
8922 "
8923{
bb621ad7 8924 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8925 FAIL;
8926
8927 /* set up operands from compare. */
8928 operands[1] = branch_cmp[0];
8929 operands[2] = branch_cmp[1];
8930
2bcb2ab3 8931 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8932 {
8933 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8934 DONE;
8935 }
8936
8ef30996
MM
8937 /* fall through and generate default code */
8938}")
8939
8940(define_insn "sltu_si"
8941 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8942 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8943 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8944 "!TARGET_MIPS16"
8ef30996 8945 "sltu\\t%0,%1,%2"
bb621ad7 8946 [(set_attr "type" "arith")
0ff83799 8947 (set_attr "mode" "SI")])
8ef30996 8948
2bcb2ab3
GK
8949(define_insn ""
8950 [(set (match_operand:SI 0 "register_operand" "=t,t")
8951 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8952 (match_operand:SI 2 "arith_operand" "d,I")))]
8953 "TARGET_MIPS16"
8954 "sltu\\t%1,%2"
8955 [(set_attr "type" "arith")
8956 (set_attr "mode" "SI")
8957 (set_attr_alternative "length"
0ff83799 8958 [(const_int 4)
2bcb2ab3 8959 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8960 (const_int 4)
8961 (const_int 8))])])
2bcb2ab3 8962
bb621ad7
JW
8963(define_insn "sltu_di"
8964 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
8965 (ltu:DI (match_operand:DI 1 "register_operand" "d")
8966 (match_operand:DI 2 "arith_operand" "dI")))]
2bcb2ab3 8967 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8968 "sltu\\t%0,%1,%2"
8969 [(set_attr "type" "arith")
0ff83799 8970 (set_attr "mode" "DI")])
bb621ad7 8971
2bcb2ab3
GK
8972(define_insn ""
8973 [(set (match_operand:DI 0 "register_operand" "=t,t")
cafe096b
EC
8974 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
8975 (match_operand:DI 2 "arith_operand" "d,I")))]
2bcb2ab3
GK
8976 "TARGET_64BIT && TARGET_MIPS16"
8977 "sltu\\t%1,%2"
8978 [(set_attr "type" "arith")
8979 (set_attr "mode" "DI")
8980 (set_attr_alternative "length"
0ff83799 8981 [(const_int 4)
2bcb2ab3 8982 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8983 (const_int 4)
8984 (const_int 8))])])
2bcb2ab3 8985
8ef30996
MM
8986(define_expand "sleu"
8987 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8988 (leu:SI (match_dup 1)
8ef30996
MM
8989 (match_dup 2)))]
8990 ""
8991 "
8992{
bb621ad7 8993 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8994 FAIL;
8995
8996 /* set up operands from compare. */
8997 operands[1] = branch_cmp[0];
8998 operands[2] = branch_cmp[1];
8999
2bcb2ab3 9000 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
9001 {
9002 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
9003 DONE;
9004 }
9005
8ef30996
MM
9006 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
9007 operands[2] = force_reg (SImode, operands[2]);
9008
9009 /* fall through and generate default code */
9010}")
9011
34b650b3
MM
9012(define_insn "sleu_si_const"
9013 [(set (match_operand:SI 0 "register_operand" "=d")
9014 (leu:SI (match_operand:SI 1 "register_operand" "d")
9015 (match_operand:SI 2 "small_int" "I")))]
2bcb2ab3 9016 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
34b650b3
MM
9017 "*
9018{
c5c76735 9019 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
34b650b3
MM
9020 return \"sltu\\t%0,%1,%2\";
9021}"
bb621ad7 9022 [(set_attr "type" "arith")
0ff83799 9023 (set_attr "mode" "SI")])
34b650b3 9024
2bcb2ab3
GK
9025(define_insn ""
9026 [(set (match_operand:SI 0 "register_operand" "=t")
9027 (leu:SI (match_operand:SI 1 "register_operand" "d")
9028 (match_operand:SI 2 "small_int" "I")))]
9029 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9030 "*
9031{
95936d18 9032 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
9033 return \"sltu\\t%1,%2\";
9034}"
9035 [(set_attr "type" "arith")
9036 (set_attr "mode" "SI")
9037 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
9038 (const_int 4)
9039 (const_int 8)))])
2bcb2ab3 9040
bb621ad7
JW
9041(define_insn "sleu_di_const"
9042 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b 9043 (leu:DI (match_operand:DI 1 "register_operand" "d")
bb621ad7 9044 (match_operand:DI 2 "small_int" "I")))]
2bcb2ab3 9045 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
bb621ad7
JW
9046 "*
9047{
c5c76735 9048 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
bb621ad7
JW
9049 return \"sltu\\t%0,%1,%2\";
9050}"
9051 [(set_attr "type" "arith")
0ff83799 9052 (set_attr "mode" "DI")])
bb621ad7 9053
2bcb2ab3
GK
9054(define_insn ""
9055 [(set (match_operand:DI 0 "register_operand" "=t")
cafe096b 9056 (leu:DI (match_operand:DI 1 "register_operand" "d")
2bcb2ab3
GK
9057 (match_operand:DI 2 "small_int" "I")))]
9058 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
9059 "*
9060{
95936d18 9061 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
9062 return \"sltu\\t%1,%2\";
9063}"
9064 [(set_attr "type" "arith")
9065 (set_attr "mode" "DI")
9066 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
9067 (const_int 4)
9068 (const_int 8)))])
2bcb2ab3 9069
34b650b3
MM
9070(define_insn "sleu_si_reg"
9071 [(set (match_operand:SI 0 "register_operand" "=d")
9072 (leu:SI (match_operand:SI 1 "register_operand" "d")
9073 (match_operand:SI 2 "register_operand" "d")))]
2bcb2ab3 9074 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
34b650b3 9075 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
bb621ad7 9076 [(set_attr "type" "arith")
34b650b3 9077 (set_attr "mode" "SI")
0ff83799 9078 (set_attr "length" "8")])
8ef30996
MM
9079
9080(define_split
9081 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 9082 (leu:SI (match_operand:SI 1 "register_operand" "")
8ef30996 9083 (match_operand:SI 2 "register_operand" "")))]
2bcb2ab3 9084 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 9085 [(set (match_dup 0)
34b650b3 9086 (ltu:SI (match_dup 2)
8ef30996
MM
9087 (match_dup 1)))
9088 (set (match_dup 0)
9089 (xor:SI (match_dup 0)
9090 (const_int 1)))]
9091 "")
9092
bb621ad7
JW
9093(define_insn "sleu_di_reg"
9094 [(set (match_operand:DI 0 "register_operand" "=d")
cafe096b
EC
9095 (leu:DI (match_operand:DI 1 "register_operand" "d")
9096 (match_operand:DI 2 "register_operand" "d")))]
2bcb2ab3 9097 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
9098 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
9099 [(set_attr "type" "arith")
9100 (set_attr "mode" "DI")
0ff83799 9101 (set_attr "length" "8")])
bb621ad7
JW
9102
9103(define_split
9104 [(set (match_operand:DI 0 "register_operand" "")
cafe096b
EC
9105 (leu:DI (match_operand:DI 1 "register_operand" "")
9106 (match_operand:DI 2 "register_operand" "")))]
2bcb2ab3
GK
9107 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
9108 && !TARGET_MIPS16"
bb621ad7
JW
9109 [(set (match_dup 0)
9110 (ltu:DI (match_dup 2)
9111 (match_dup 1)))
9112 (set (match_dup 0)
9113 (xor:DI (match_dup 0)
9114 (const_int 1)))]
9115 "")
9116
34b650b3
MM
9117\f
9118;;
9119;; ....................
9120;;
9121;; FLOATING POINT COMPARISONS
9122;;
9123;; ....................
9124
ce3649d2
EC
9125(define_insn "sunordered_df"
9126 [(set (match_operand:CC 0 "register_operand" "=z")
9127 (unordered:CC (match_operand:DF 1 "register_operand" "f")
9128 (match_operand:DF 2 "register_operand" "f")))]
9129 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9130 "*
9131{
9132 return mips_fill_delay_slot (\"c.un.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9133}"
9134 [(set_attr "type" "fcmp")
9135 (set_attr "mode" "FPSW")])
9136
ce3649d2
EC
9137(define_insn "sunlt_df"
9138 [(set (match_operand:CC 0 "register_operand" "=z")
9139 (unlt:CC (match_operand:DF 1 "register_operand" "f")
9140 (match_operand:DF 2 "register_operand" "f")))]
9141 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9142 "*
9143{
9144 return mips_fill_delay_slot (\"c.ult.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9145}"
9146 [(set_attr "type" "fcmp")
9147 (set_attr "mode" "FPSW")])
9148
9149(define_insn "suneq_df"
9150 [(set (match_operand:CC 0 "register_operand" "=z")
9151 (uneq:CC (match_operand:DF 1 "register_operand" "f")
9152 (match_operand:DF 2 "register_operand" "f")))]
9153 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9154 "*
9155{
9156 return mips_fill_delay_slot (\"c.ueq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9157}"
9158 [(set_attr "type" "fcmp")
9159 (set_attr "mode" "FPSW")])
9160
ce3649d2
EC
9161(define_insn "sunle_df"
9162 [(set (match_operand:CC 0 "register_operand" "=z")
9163 (unle:CC (match_operand:DF 1 "register_operand" "f")
9164 (match_operand:DF 2 "register_operand" "f")))]
9165 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9166 "*
9167{
9168 return mips_fill_delay_slot (\"c.ule.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9169}"
9170 [(set_attr "type" "fcmp")
9171 (set_attr "mode" "FPSW")])
9172
34b650b3 9173(define_insn "seq_df"
b8eb88d0
ILT
9174 [(set (match_operand:CC 0 "register_operand" "=z")
9175 (eq:CC (match_operand:DF 1 "register_operand" "f")
9176 (match_operand:DF 2 "register_operand" "f")))]
46299de9 9177 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
9178 "*
9179{
b8eb88d0 9180 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
9181}"
9182 [(set_attr "type" "fcmp")
0ff83799 9183 (set_attr "mode" "FPSW")])
34b650b3
MM
9184
9185(define_insn "slt_df"
b8eb88d0
ILT
9186 [(set (match_operand:CC 0 "register_operand" "=z")
9187 (lt:CC (match_operand:DF 1 "register_operand" "f")
9188 (match_operand:DF 2 "register_operand" "f")))]
46299de9 9189 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
9190 "*
9191{
b8eb88d0 9192 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
9193}"
9194 [(set_attr "type" "fcmp")
0ff83799 9195 (set_attr "mode" "FPSW")])
34b650b3
MM
9196
9197(define_insn "sle_df"
b8eb88d0
ILT
9198 [(set (match_operand:CC 0 "register_operand" "=z")
9199 (le:CC (match_operand:DF 1 "register_operand" "f")
9200 (match_operand:DF 2 "register_operand" "f")))]
46299de9 9201 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
9202 "*
9203{
b8eb88d0 9204 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
9205}"
9206 [(set_attr "type" "fcmp")
0ff83799 9207 (set_attr "mode" "FPSW")])
34b650b3
MM
9208
9209(define_insn "sgt_df"
b8eb88d0
ILT
9210 [(set (match_operand:CC 0 "register_operand" "=z")
9211 (gt:CC (match_operand:DF 1 "register_operand" "f")
9212 (match_operand:DF 2 "register_operand" "f")))]
46299de9 9213 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
9214 "*
9215{
b8eb88d0 9216 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
9217}"
9218 [(set_attr "type" "fcmp")
0ff83799 9219 (set_attr "mode" "FPSW")])
34b650b3
MM
9220
9221(define_insn "sge_df"
b8eb88d0
ILT
9222 [(set (match_operand:CC 0 "register_operand" "=z")
9223 (ge:CC (match_operand:DF 1 "register_operand" "f")
9224 (match_operand:DF 2 "register_operand" "f")))]
46299de9 9225 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
9226 "*
9227{
b8eb88d0 9228 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
9229}"
9230 [(set_attr "type" "fcmp")
0ff83799 9231 (set_attr "mode" "FPSW")])
34b650b3 9232
ce3649d2
EC
9233(define_insn "sunordered_sf"
9234 [(set (match_operand:CC 0 "register_operand" "=z")
9235 (unordered:CC (match_operand:SF 1 "register_operand" "f")
9236 (match_operand:SF 2 "register_operand" "f")))]
9237 "TARGET_HARD_FLOAT"
9238 "*
9239{
9240 return mips_fill_delay_slot (\"c.un.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9241}"
9242 [(set_attr "type" "fcmp")
9243 (set_attr "mode" "FPSW")])
9244
ce3649d2
EC
9245(define_insn "sunlt_sf"
9246 [(set (match_operand:CC 0 "register_operand" "=z")
9247 (unlt:CC (match_operand:SF 1 "register_operand" "f")
9248 (match_operand:SF 2 "register_operand" "f")))]
e49ec17d 9249 "TARGET_HARD_FLOAT"
ce3649d2
EC
9250 "*
9251{
9252 return mips_fill_delay_slot (\"c.ult.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9253}"
9254 [(set_attr "type" "fcmp")
9255 (set_attr "mode" "FPSW")])
9256
9257(define_insn "suneq_sf"
9258 [(set (match_operand:CC 0 "register_operand" "=z")
9259 (uneq:CC (match_operand:SF 1 "register_operand" "f")
9260 (match_operand:SF 2 "register_operand" "f")))]
e49ec17d 9261 "TARGET_HARD_FLOAT"
ce3649d2
EC
9262 "*
9263{
9264 return mips_fill_delay_slot (\"c.ueq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9265}"
9266 [(set_attr "type" "fcmp")
9267 (set_attr "mode" "FPSW")])
9268
ce3649d2
EC
9269(define_insn "sunle_sf"
9270 [(set (match_operand:CC 0 "register_operand" "=z")
9271 (unle:CC (match_operand:SF 1 "register_operand" "f")
9272 (match_operand:SF 2 "register_operand" "f")))]
e49ec17d 9273 "TARGET_HARD_FLOAT"
ce3649d2
EC
9274 "*
9275{
9276 return mips_fill_delay_slot (\"c.ule.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
9277}"
9278 [(set_attr "type" "fcmp")
9279 (set_attr "mode" "FPSW")])
9280
34b650b3 9281(define_insn "seq_sf"
b8eb88d0
ILT
9282 [(set (match_operand:CC 0 "register_operand" "=z")
9283 (eq:CC (match_operand:SF 1 "register_operand" "f")
9284 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 9285 "TARGET_HARD_FLOAT"
34b650b3
MM
9286 "*
9287{
b8eb88d0 9288 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
9289}"
9290 [(set_attr "type" "fcmp")
0ff83799 9291 (set_attr "mode" "FPSW")])
34b650b3
MM
9292
9293(define_insn "slt_sf"
b8eb88d0
ILT
9294 [(set (match_operand:CC 0 "register_operand" "=z")
9295 (lt:CC (match_operand:SF 1 "register_operand" "f")
9296 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 9297 "TARGET_HARD_FLOAT"
34b650b3
MM
9298 "*
9299{
b8eb88d0 9300 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
9301}"
9302 [(set_attr "type" "fcmp")
0ff83799 9303 (set_attr "mode" "FPSW")])
34b650b3
MM
9304
9305(define_insn "sle_sf"
b8eb88d0
ILT
9306 [(set (match_operand:CC 0 "register_operand" "=z")
9307 (le:CC (match_operand:SF 1 "register_operand" "f")
9308 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 9309 "TARGET_HARD_FLOAT"
34b650b3
MM
9310 "*
9311{
b8eb88d0 9312 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
9313}"
9314 [(set_attr "type" "fcmp")
0ff83799 9315 (set_attr "mode" "FPSW")])
34b650b3
MM
9316
9317(define_insn "sgt_sf"
b8eb88d0
ILT
9318 [(set (match_operand:CC 0 "register_operand" "=z")
9319 (gt:CC (match_operand:SF 1 "register_operand" "f")
9320 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 9321 "TARGET_HARD_FLOAT"
34b650b3
MM
9322 "*
9323{
b8eb88d0 9324 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
9325}"
9326 [(set_attr "type" "fcmp")
0ff83799 9327 (set_attr "mode" "FPSW")])
34b650b3
MM
9328
9329(define_insn "sge_sf"
b8eb88d0
ILT
9330 [(set (match_operand:CC 0 "register_operand" "=z")
9331 (ge:CC (match_operand:SF 1 "register_operand" "f")
9332 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 9333 "TARGET_HARD_FLOAT"
34b650b3
MM
9334 "*
9335{
b8eb88d0 9336 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
9337}"
9338 [(set_attr "type" "fcmp")
0ff83799 9339 (set_attr "mode" "FPSW")])
34b650b3 9340
8ef30996
MM
9341\f
9342;;
9343;; ....................
9344;;
9345;; UNCONDITIONAL BRANCHES
9346;;
9347;; ....................
9348
9349;; Unconditional branches.
9350
9351(define_insn "jump"
9352 [(set (pc)
9353 (label_ref (match_operand 0 "" "")))]
2bcb2ab3 9354 "!TARGET_MIPS16"
8ef30996
MM
9355 "*
9356{
852dff61
AO
9357 if (flag_pic && ! TARGET_EMBEDDED_PIC)
9358 {
9359 if (get_attr_length (insn) <= 8)
9360 return \"%*b\\t%l0\";
9361 else if (Pmode == DImode)
9362 return \"%[dla\\t%@,%l0\;%*jr\\t%@%]\";
9363 else
9364 return \"%[la\\t%@,%l0\;%*jr\\t%@%]\";
9365 }
7a38df19 9366 else
8ef30996
MM
9367 return \"%*j\\t%l0\";
9368}"
9369 [(set_attr "type" "jump")
852dff61
AO
9370 (set_attr "mode" "none")
9371 (set (attr "length")
9372 ;; we can't use `j' when emitting non-embedded PIC, so we emit
9373 ;; branch, if it's in range, or load the address of the branch
9374 ;; target into $at in a PIC-compatible way and then jump to it.
cafe096b 9375 (if_then_else
852dff61
AO
9376 (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
9377 (const_int 0))
9378 (lt (abs (minus (match_dup 0)
9379 (plus (pc) (const_int 4))))
9380 (const_int 131072)))
9381 (const_int 4) (const_int 16)))])
8ef30996 9382
2bcb2ab3
GK
9383;; We need a different insn for the mips16, because a mips16 branch
9384;; does not have a delay slot.
9385
9386(define_insn ""
9387 [(set (pc)
9388 (label_ref (match_operand 0 "" "")))]
852dff61 9389 "TARGET_MIPS16"
2bcb2ab3
GK
9390 "b\\t%l0"
9391 [(set_attr "type" "branch")
9392 (set_attr "mode" "none")
0ff83799 9393 (set_attr "length" "8")])
2bcb2ab3 9394
bb621ad7
JW
9395(define_expand "indirect_jump"
9396 [(set (pc) (match_operand 0 "register_operand" "d"))]
8ef30996 9397 ""
bb621ad7
JW
9398 "
9399{
9400 rtx dest;
9401
9402 if (operands[0]) /* eliminate unused code warnings */
9403 {
9404 dest = operands[0];
9405 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9406 operands[0] = copy_to_mode_reg (Pmode, dest);
9407
1eeed24e 9408 if (!(Pmode == DImode))
bb621ad7
JW
9409 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9410 else
9411 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9412
9413 DONE;
9414 }
9415}")
9416
9417(define_insn "indirect_jump_internal1"
9418 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
1eeed24e 9419 "!(Pmode == DImode)"
bb621ad7
JW
9420 "%*j\\t%0"
9421 [(set_attr "type" "jump")
0ff83799 9422 (set_attr "mode" "none")])
bb621ad7
JW
9423
9424(define_insn "indirect_jump_internal2"
cafe096b 9425 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
1eeed24e 9426 "Pmode == DImode"
8ef30996
MM
9427 "%*j\\t%0"
9428 [(set_attr "type" "jump")
0ff83799 9429 (set_attr "mode" "none")])
8ef30996 9430
bb621ad7 9431(define_expand "tablejump"
8ef30996 9432 [(set (pc)
bb621ad7 9433 (match_operand 0 "register_operand" "d"))
8ef30996
MM
9434 (use (label_ref (match_operand 1 "" "")))]
9435 ""
bb621ad7
JW
9436 "
9437{
bb621ad7
JW
9438 if (operands[0]) /* eliminate unused code warnings */
9439 {
2bcb2ab3
GK
9440 if (TARGET_MIPS16)
9441 {
9442 if (GET_MODE (operands[0]) != HImode)
9443 abort ();
1eeed24e 9444 if (!(Pmode == DImode))
bf4f78ee 9445 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
2bcb2ab3 9446 else
bf4f78ee 9447 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
2bcb2ab3
GK
9448 DONE;
9449 }
9450
cafe096b 9451 if (GET_MODE (operands[0]) != ptr_mode)
bb621ad7
JW
9452 abort ();
9453
cafe096b
EC
9454 if (TARGET_GPWORD)
9455 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
9456 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
bb621ad7 9457
cafe096b
EC
9458 if (Pmode == SImode)
9459 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9460 else
9461 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
bb621ad7
JW
9462 DONE;
9463 }
9464}")
9465
9466(define_insn "tablejump_internal1"
9467 [(set (pc)
9468 (match_operand:SI 0 "register_operand" "d"))
9469 (use (label_ref (match_operand 1 "" "")))]
cafe096b 9470 ""
9fa0af71 9471 "%*j\\t%0"
bb621ad7 9472 [(set_attr "type" "jump")
0ff83799 9473 (set_attr "mode" "none")])
bb621ad7
JW
9474
9475(define_insn "tablejump_internal2"
9476 [(set (pc)
cafe096b 9477 (match_operand:DI 0 "register_operand" "d"))
bb621ad7 9478 (use (label_ref (match_operand 1 "" "")))]
cafe096b 9479 "TARGET_64BIT"
9fa0af71
JW
9480 "%*j\\t%0"
9481 [(set_attr "type" "jump")
0ff83799 9482 (set_attr "mode" "none")])
9fa0af71 9483
2bcb2ab3
GK
9484(define_expand "tablejump_mips161"
9485 [(set (pc) (plus:SI (sign_extend:SI
9486 (match_operand:HI 0 "register_operand" "d"))
cf45bb06 9487 (label_ref:SI (match_operand 1 "" ""))))]
1eeed24e 9488 "TARGET_MIPS16 && !(Pmode == DImode)"
2bcb2ab3
GK
9489 "
9490{
9491 if (operands[0]) /* eliminate unused code warnings. */
9492 {
9493 rtx t1, t2, t3;
9494
9495 t1 = gen_reg_rtx (SImode);
9496 t2 = gen_reg_rtx (SImode);
9497 t3 = gen_reg_rtx (SImode);
9498 emit_insn (gen_extendhisi2 (t1, operands[0]));
6bbdc759 9499 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
2bcb2ab3 9500 emit_insn (gen_addsi3 (t3, t1, t2));
bf4f78ee 9501 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
2bcb2ab3
GK
9502 DONE;
9503 }
9504}")
9505
9506(define_expand "tablejump_mips162"
9507 [(set (pc) (plus:DI (sign_extend:DI
9508 (match_operand:HI 0 "register_operand" "d"))
cf45bb06 9509 (label_ref:DI (match_operand 1 "" ""))))]
1eeed24e 9510 "TARGET_MIPS16 && Pmode == DImode"
2bcb2ab3
GK
9511 "
9512{
9513 if (operands[0]) /* eliminate unused code warnings. */
9514 {
9515 rtx t1, t2, t3;
9516
9517 t1 = gen_reg_rtx (DImode);
9518 t2 = gen_reg_rtx (DImode);
9519 t3 = gen_reg_rtx (DImode);
9520 emit_insn (gen_extendhidi2 (t1, operands[0]));
6bbdc759 9521 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
2bcb2ab3 9522 emit_insn (gen_adddi3 (t3, t1, t2));
bf4f78ee 9523 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
2bcb2ab3 9524 DONE;
cafe096b
EC
9525 }
9526}")
8ef30996 9527
e0bfcea5
ILT
9528;; Implement a switch statement when generating embedded PIC code.
9529;; Switches are implemented by `tablejump' when not using -membedded-pic.
9530
9531(define_expand "casesi"
9532 [(set (match_dup 5)
9533 (minus:SI (match_operand:SI 0 "register_operand" "d")
9534 (match_operand:SI 1 "arith_operand" "dI")))
9535 (set (cc0)
9536 (compare:CC (match_dup 5)
9537 (match_operand:SI 2 "arith_operand" "")))
9538 (set (pc)
9539 (if_then_else (gtu (cc0)
9540 (const_int 0))
9541 (label_ref (match_operand 4 "" ""))
9542 (pc)))
9543 (parallel
9544 [(set (pc)
9545 (mem:SI (plus:SI (mult:SI (match_dup 5)
9546 (const_int 4))
9547 (label_ref (match_operand 3 "" "")))))
9548 (clobber (match_scratch:SI 6 ""))
9549 (clobber (reg:SI 31))])]
9550 "TARGET_EMBEDDED_PIC"
9551 "
9552{
e0bfcea5
ILT
9553 if (operands[0])
9554 {
9555 rtx reg = gen_reg_rtx (SImode);
9556
e0bfcea5
ILT
9557 /* If the index is too large, go to the default label. */
9558 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9559 emit_insn (gen_cmpsi (reg, operands[2]));
9560 emit_insn (gen_bgtu (operands[4]));
9561
9562 /* Do the PIC jump. */
9c9e7632 9563 if (Pmode != DImode)
7a38df19 9564 emit_jump_insn (gen_casesi_internal (reg, operands[3],
9c9e7632
GK
9565 gen_reg_rtx (SImode)));
9566 else
7a38df19 9567 emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9c9e7632 9568 gen_reg_rtx (DImode)));
e0bfcea5
ILT
9569
9570 DONE;
9571 }
9572}")
9573
9574;; An embedded PIC switch statement looks like this:
9575;; bal $LS1
810c1b83 9576;; sll $reg,$index,2
e0bfcea5
ILT
9577;; $LS1:
9578;; addu $reg,$reg,$31
9579;; lw $reg,$L1-$LS1($reg)
9580;; addu $reg,$reg,$31
9581;; j $reg
9582;; $L1:
9583;; .word case1-$LS1
9584;; .word case2-$LS1
9585;; ...
9586
9587(define_insn "casesi_internal"
9588 [(set (pc)
9589 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9590 (const_int 4))
9591 (label_ref (match_operand 1 "" "")))))
0e7e9155 9592 (clobber (match_operand:SI 2 "register_operand" "=d"))
e0bfcea5
ILT
9593 (clobber (reg:SI 31))]
9594 "TARGET_EMBEDDED_PIC"
810c1b83 9595 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
246a46e0 9596lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2"
e0bfcea5
ILT
9597 [(set_attr "type" "jump")
9598 (set_attr "mode" "none")
0ff83799 9599 (set_attr "length" "24")])
e0bfcea5 9600
6a5ea3f4
CD
9601;; This code assumes that the table index will never be >= 29 bits wide,
9602;; which allows the 'sign extend' from SI to DI be a no-op.
9c9e7632
GK
9603(define_insn "casesi_internal_di"
9604 [(set (pc)
7a38df19 9605 (mem:DI (plus:DI (sign_extend:DI
9c9e7632 9606 (mult:SI (match_operand:SI 0 "register_operand" "d")
6a5ea3f4 9607 (const_int 8)))
9c9e7632
GK
9608 (label_ref (match_operand 1 "" "")))))
9609 (clobber (match_operand:DI 2 "register_operand" "=d"))
9610 (clobber (reg:DI 31))]
9611 "TARGET_EMBEDDED_PIC"
6a5ea3f4 9612 "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
246a46e0 9613ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
9c9e7632
GK
9614 [(set_attr "type" "jump")
9615 (set_attr "mode" "none")
9616 (set_attr "length" "24")])
9617
6fd1c67b
RH
9618;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9619;; possible to either pull it off the stack (in the o32 case) or recalculate
9620;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9621;; this is easy.
9622
9623(define_expand "builtin_setjmp_setup"
41f8d041 9624 [(unspec [(match_operand 0 "register_operand" "r")] UNSPEC_SETJMP)]
6fd1c67b 9625 "TARGET_ABICALLS"
d5d1738a
JW
9626 "
9627{
1eeed24e 9628 if (Pmode == DImode)
6fd1c67b
RH
9629 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9630 else
9631 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9632 DONE;
d5d1738a 9633}")
c85f7c16 9634
6fd1c67b
RH
9635(define_expand "builtin_setjmp_setup_32"
9636 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9637 (const_int 12)))
9638 (reg:SI 28))]
1eeed24e 9639 "TARGET_ABICALLS && ! (Pmode == DImode)"
6fd1c67b 9640 "")
c85f7c16 9641
6fd1c67b
RH
9642(define_expand "builtin_setjmp_setup_64"
9643 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9644 (const_int 24)))
9645 (reg:DI 28))]
1eeed24e 9646 "TARGET_ABICALLS && Pmode == DImode"
6fd1c67b
RH
9647 "")
9648
7a38df19 9649;; For o32/n32/n64, we need to arrange for longjmp to put the
6fd1c67b
RH
9650;; target address in t9 so that we can use it for loading $gp.
9651
9652(define_expand "builtin_longjmp"
41f8d041 9653 [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPEC_LONGJMP)]
6fd1c67b 9654 "TARGET_ABICALLS"
c85f7c16
JL
9655 "
9656{
6fd1c67b 9657 /* The elements of the buffer are, in order: */
1eeed24e 9658 int W = (Pmode == DImode ? 8 : 4);
6fd1c67b
RH
9659 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9660 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9661 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9662 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9663 rtx pv = gen_rtx_REG (Pmode, 25);
9664 rtx gp = gen_rtx_REG (Pmode, 28);
9665
9666 /* This bit is the same as expand_builtin_longjmp. */
9667 emit_move_insn (hard_frame_pointer_rtx, fp);
9668 emit_move_insn (pv, lab);
9669 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9670 emit_move_insn (gp, gpv);
9671 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9672 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9673 emit_insn (gen_rtx_USE (VOIDmode, gp));
9674 emit_indirect_jump (pv);
9675 DONE;
c85f7c16 9676}")
0fb5ac6f
MM
9677\f
9678;;
9679;; ....................
9680;;
9681;; Function prologue/epilogue
9682;;
9683;; ....................
9684;;
9685
9686(define_expand "prologue"
9687 [(const_int 1)]
9688 ""
9689 "
9690{
9691 if (mips_isa >= 0) /* avoid unused code warnings */
9692 {
9693 mips_expand_prologue ();
9694 DONE;
9695 }
9696}")
9697
d8d5b1e1
MM
9698;; Block any insns from being moved before this point, since the
9699;; profiling call to mcount can use various registers that aren't
9700;; saved or used to pass arguments.
9701
9702(define_insn "blockage"
41f8d041 9703 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
d8d5b1e1
MM
9704 ""
9705 ""
9706 [(set_attr "type" "unknown")
9707 (set_attr "mode" "none")
9708 (set_attr "length" "0")])
9709
1f2d8f51
JL
9710(define_expand "epilogue"
9711 [(const_int 2)]
9712 ""
1f2d8f51 9713{
cafe096b
EC
9714 mips_expand_epilogue (false);
9715 DONE;
9716})
9717
9718(define_expand "sibcall_epilogue"
9719 [(const_int 2)]
9720 ""
9721{
9722 mips_expand_epilogue (true);
9723 DONE;
9724})
0fb5ac6f 9725
1f2d8f51
JL
9726;; Trivial return. Make it look like a normal return insn as that
9727;; allows jump optimizations to work better .
9728(define_insn "return"
9729 [(return)]
9730 "mips_can_use_return_insn ()"
8fa4e1b4 9731 "%*j\\t$31"
1f2d8f51 9732 [(set_attr "type" "jump")
0ff83799 9733 (set_attr "mode" "none")])
1f2d8f51
JL
9734
9735;; Normal return.
0e7e9155 9736
1f2d8f51 9737(define_insn "return_internal"
0e7e9155 9738 [(use (match_operand 0 "pmode_register_operand" ""))
1f2d8f51
JL
9739 (return)]
9740 ""
2bcb2ab3
GK
9741 "*
9742{
9743 return \"%*j\\t%0\";
9744}"
1f2d8f51 9745 [(set_attr "type" "jump")
0ff83799 9746 (set_attr "mode" "none")])
7a38df19 9747
92544bdf
ILT
9748;; When generating embedded PIC code we need to get the address of the
9749;; current function. This specialized instruction does just that.
9750
9751(define_insn "get_fnaddr"
0d3b5987 9752 [(set (match_operand 0 "register_operand" "=d")
41f8d041 9753 (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
92544bdf
ILT
9754 (clobber (reg:SI 31))]
9755 "TARGET_EMBEDDED_PIC
9756 && GET_CODE (operands[1]) == SYMBOL_REF"
ae598ab9 9757 "%($LF%= = . + 8\;bal\\t$LF%=\;nop;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
92544bdf
ILT
9758 [(set_attr "type" "call")
9759 (set_attr "mode" "none")
7fa9ed65 9760 (set_attr "length" "20")])
92544bdf 9761
9e800206
RH
9762;; This is used in compiling the unwind routines.
9763(define_expand "eh_return"
9764 [(use (match_operand 0 "general_operand" ""))
9765 (use (match_operand 1 "general_operand" ""))]
9766 ""
9767 "
9768{
9769 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
9770
9771 if (GET_MODE (operands[1]) != gpr_mode)
9772 operands[1] = convert_to_mode (gpr_mode, operands[1], 0);
9773 if (TARGET_64BIT)
9774 emit_insn (gen_eh_set_lr_di (operands[1]));
9775 else
9776 emit_insn (gen_eh_set_lr_si (operands[1]));
9777
9778 emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
9779 DONE;
9780}")
9781
9782;; Clobber the return address on the stack. We can't expand this
9783;; until we know where it will be put in the stack frame.
9784
9785(define_insn "eh_set_lr_si"
ead0c1d5
RS
9786 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
9787 (clobber (match_scratch:SI 1 "=&d"))]
9e800206
RH
9788 "! TARGET_64BIT"
9789 "#")
9790
9791(define_insn "eh_set_lr_di"
ead0c1d5
RS
9792 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
9793 (clobber (match_scratch:DI 1 "=&d"))]
9e800206
RH
9794 "TARGET_64BIT"
9795 "#")
9796
9797(define_split
41f8d041 9798 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
13c508d9 9799 (clobber (match_scratch 1 ""))]
2ca2d9ee 9800 "reload_completed && !TARGET_DEBUG_D_MODE"
9e800206
RH
9801 [(const_int 0)]
9802 "
9803{
b2471838 9804 mips_set_return_address (operands[0], operands[1]);
9e800206
RH
9805 DONE;
9806}")
68f4edf0
RH
9807
9808(define_insn "exception_receiver"
41f8d041 9809 [(unspec_volatile [(const_int 0)] UNSPEC_EH_RECEIVER)]
68f4edf0 9810 "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
b2471838 9811 "* return mips_restore_gp (operands, insn);"
68f4edf0
RH
9812 [(set_attr "type" "load")
9813 (set_attr "length" "8")])
8ef30996
MM
9814\f
9815;;
9816;; ....................
9817;;
9818;; FUNCTION CALLS
9819;;
9820;; ....................
9821
cafe096b 9822;; Sibling calls. All these patterns use direct jumps.
3f1f8d8c 9823
cafe096b
EC
9824;; call_insn_operand will only accepts constant addresses if a direct
9825;; jump is acceptable. Since the 'S' constraint is defined in terms of
9826;; call_insn_operand, the same is true of the contraints.
2bcb2ab3 9827
cafe096b
EC
9828;; When we use an indirect jump, we need a register that will be
9829;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
9830;; use $25 for this purpose -- and $25 is never clobbered by the
9831;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
8ef30996 9832
cafe096b 9833(define_expand "sibcall"
aa4e54c4
JW
9834 [(parallel [(call (match_operand 0 "" "")
9835 (match_operand 1 "" ""))
cafe096b
EC
9836 (use (match_operand 2 "" "")) ;; next_arg_reg
9837 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9838 "TARGET_SIBCALLS"
8ef30996 9839{
cafe096b
EC
9840 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
9841 DONE;
9842})
3f1f8d8c 9843
cafe096b
EC
9844(define_insn "sibcall_internal"
9845 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
9846 (match_operand 1 "" ""))]
9847 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
9848 "@
9849 %*jr\\t%0
9850 %*j\\t%0"
9851 [(set_attr "type" "call")])
8ef30996 9852
cafe096b 9853(define_expand "sibcall_value"
aa4e54c4
JW
9854 [(parallel [(set (match_operand 0 "" "")
9855 (call (match_operand 1 "" "")
9856 (match_operand 2 "" "")))
cafe096b
EC
9857 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9858 "TARGET_SIBCALLS"
84a92af4 9859{
cafe096b
EC
9860 mips_expand_call (operands[0], XEXP (operands[1], 0),
9861 operands[2], operands[3], true);
9862 DONE;
9863})
6d4503c3 9864
cafe096b
EC
9865(define_insn "sibcall_value_internal"
9866 [(set (match_operand 0 "register_operand" "=df,df")
9867 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
9868 (match_operand 2 "" "")))]
9869 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
9870 "@
9871 %*jr\\t%1
9872 %*j\\t%1"
9873 [(set_attr "type" "call")])
9874
9875(define_insn "sibcall_value_multiple_internal"
9876 [(set (match_operand 0 "register_operand" "=df,df")
9877 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
9878 (match_operand 2 "" "")))
9879 (set (match_operand 3 "register_operand" "=df,df")
9880 (call (mem:SI (match_dup 1))
9881 (match_dup 2)))]
9882 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
9883 "@
9884 %*jr\\t%1
9885 %*j\\t%1"
9886 [(set_attr "type" "call")])
d1399bd0 9887
cafe096b
EC
9888(define_expand "call"
9889 [(parallel [(call (match_operand 0 "" "")
9890 (match_operand 1 "" ""))
9891 (use (match_operand 2 "" "")) ;; next_arg_reg
9892 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9893 ""
bb621ad7 9894{
cafe096b
EC
9895 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
9896 DONE;
9897})
bb621ad7 9898
cafe096b
EC
9899(define_insn_and_split "call_internal"
9900 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
9901 (match_operand 1 "" ""))
9902 (clobber (reg:SI 31))]
9903 ""
9904 "%*jal\\t%0"
9905 "reload_completed && TARGET_SPLIT_CALLS"
9906 [(const_int 0)]
9907 {
9908 emit_call_insn (gen_call_split (operands[0], operands[1]));
9909 emit_insn (gen_exception_receiver ());
9910 DONE;
9911 }
9912 [(set_attr "jal" "indirect,direct")
9913 (set_attr "extended_mips16" "no,yes")])
9914
9915(define_insn "call_split"
9916 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
9917 (match_operand 1 "" ""))
9918 (clobber (reg:SI 31))
9919 (const_int 1)]
9920 "TARGET_SPLIT_CALLS"
9921 "%*jalr\\t%0"
9922 [(set_attr "type" "call")])
84a92af4 9923
cafe096b 9924(define_expand "call_value"
aa4e54c4
JW
9925 [(parallel [(set (match_operand 0 "" "")
9926 (call (match_operand 1 "" "")
9927 (match_operand 2 "" "")))
cafe096b 9928 (use (match_operand 3 "" ""))])] ;; next_arg_reg
aa4e54c4 9929 ""
8f7f2b3d 9930{
cafe096b
EC
9931 mips_expand_call (operands[0], XEXP (operands[1], 0),
9932 operands[2], operands[3], false);
9933 DONE;
9934})
8f7f2b3d 9935
cafe096b
EC
9936(define_insn_and_split "call_value_internal"
9937 [(set (match_operand 0 "register_operand" "=df,df")
9938 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
9939 (match_operand 2 "" "")))
9940 (clobber (reg:SI 31))]
9941 ""
9942 "%*jal\\t%1"
9943 "reload_completed && TARGET_SPLIT_CALLS"
9944 [(const_int 0)]
9945 {
9946 emit_call_insn (gen_call_value_split (operands[0], operands[1],
9947 operands[2]));
9948 emit_insn (gen_exception_receiver ());
9949 DONE;
9950 }
9951 [(set_attr "jal" "indirect,direct")
9952 (set_attr "extended_mips16" "no,yes")])
9953
9954(define_insn "call_value_split"
9955 [(set (match_operand 0 "register_operand" "=df")
9956 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
9957 (match_operand 2 "" "")))
9958 (clobber (reg:SI 31))
9959 (const_int 1)]
9960 "TARGET_SPLIT_CALLS"
9961 "%*jalr\\t%1"
9962 [(set_attr "type" "call")])
9963
9964(define_insn_and_split "call_value_multiple_internal"
9965 [(set (match_operand 0 "register_operand" "=df,df")
9966 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
9967 (match_operand 2 "" "")))
9968 (set (match_operand 3 "register_operand" "=df,df")
9969 (call (mem:SI (match_dup 1))
9970 (match_dup 2)))
9971 (clobber (reg:SI 31))]
9972 ""
9973 "%*jal\\t%1"
9974 "reload_completed && TARGET_SPLIT_CALLS"
9975 [(const_int 0)]
9976 {
9977 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
9978 operands[2], operands[3]));
9979 emit_insn (gen_exception_receiver ());
9980 DONE;
9981 }
9982 [(set_attr "jal" "indirect,direct")
9983 (set_attr "extended_mips16" "no,yes")])
9984
9985(define_insn "call_value_multiple_split"
bd16a708 9986 [(set (match_operand 0 "register_operand" "=df")
cafe096b
EC
9987 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
9988 (match_operand 2 "" "")))
bd16a708 9989 (set (match_operand 3 "register_operand" "=df")
cafe096b
EC
9990 (call (mem:SI (match_dup 1))
9991 (match_dup 2)))
9992 (clobber (reg:SI 31))
9993 (const_int 1)]
9994 "TARGET_SPLIT_CALLS"
9995 "%*jalr\\t%1"
9996 [(set_attr "type" "call")])
bd16a708 9997
a93821e9
TW
9998;; Call subroutine returning any type.
9999
10000(define_expand "untyped_call"
10001 [(parallel [(call (match_operand 0 "" "")
10002 (const_int 0))
10003 (match_operand 1 "" "")
10004 (match_operand 2 "" "")])]
10005 ""
10006 "
10007{
cafe096b 10008 int i;
a93821e9 10009
cafe096b 10010 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
a93821e9 10011
cafe096b
EC
10012 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10013 {
10014 rtx set = XVECEXP (operands[2], 0, i);
10015 emit_move_insn (SET_DEST (set), SET_SRC (set));
740b4585 10016 }
cafe096b
EC
10017
10018 emit_insn (gen_blockage ());
10019 DONE;
a93821e9 10020}")
8ef30996
MM
10021\f
10022;;
10023;; ....................
10024;;
10025;; MISC.
10026;;
10027;; ....................
10028;;
10029
8f2e3902
EC
10030
10031(define_expand "prefetch"
10032 [(prefetch (match_operand 0 "address_operand" "")
10033 (match_operand 1 "const_int_operand" "")
10034 (match_operand 2 "const_int_operand" ""))]
10035 "ISA_HAS_PREFETCH"
cafe096b
EC
10036{
10037 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
10038 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10039})
8f2e3902
EC
10040
10041(define_insn "prefetch_si_address"
10042 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
10043 (match_operand:SI 3 "const_int_operand" "i"))
10044 (match_operand:SI 1 "const_int_operand" "n")
10045 (match_operand:SI 2 "const_int_operand" "n"))]
10046 "ISA_HAS_PREFETCH && Pmode == SImode"
10047 "* return mips_emit_prefetch (operands);"
cafe096b 10048 [(set_attr "type" "prefetch")])
8f2e3902
EC
10049
10050(define_insn "prefetch_si"
10051 [(prefetch (match_operand:SI 0 "register_operand" "r")
10052 (match_operand:SI 1 "const_int_operand" "n")
10053 (match_operand:SI 2 "const_int_operand" "n"))]
10054 "ISA_HAS_PREFETCH && Pmode == SImode"
10055 "* return mips_emit_prefetch (operands);"
cafe096b 10056 [(set_attr "type" "prefetch")])
8f2e3902
EC
10057
10058(define_insn "prefetch_di_address"
cafe096b 10059 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8f2e3902
EC
10060 (match_operand:DI 3 "const_int_operand" "i"))
10061 (match_operand:DI 1 "const_int_operand" "n")
10062 (match_operand:DI 2 "const_int_operand" "n"))]
10063 "ISA_HAS_PREFETCH && Pmode == DImode"
10064 "* return mips_emit_prefetch (operands);"
cafe096b 10065 [(set_attr "type" "prefetch")])
8f2e3902
EC
10066
10067(define_insn "prefetch_di"
cafe096b 10068 [(prefetch (match_operand:DI 0 "register_operand" "r")
8f2e3902
EC
10069 (match_operand:DI 1 "const_int_operand" "n")
10070 (match_operand:DI 2 "const_int_operand" "n"))]
10071 "ISA_HAS_PREFETCH && Pmode == DImode"
10072 "* return mips_emit_prefetch (operands);"
cafe096b 10073 [(set_attr "type" "prefetch")])
8f2e3902 10074
8ef30996
MM
10075(define_insn "nop"
10076 [(const_int 0)]
10077 ""
10078 "%(nop%)"
10079 [(set_attr "type" "nop")
0ff83799 10080 (set_attr "mode" "none")])
8ef30996 10081
e454beb7
ILT
10082;; The MIPS chip does not seem to require stack probes.
10083;;
10084;; (define_expand "probe"
10085;; [(set (match_dup 0)
10086;; (match_dup 1))]
10087;; ""
10088;; "
10089;; {
10090;; operands[0] = gen_reg_rtx (SImode);
c5c76735 10091;; operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
e454beb7 10092;; MEM_VOLATILE_P (operands[1]) = TRUE;
7a38df19 10093;;
e454beb7
ILT
10094;; /* fall through and generate default code */
10095;; }")
10096;;
e19ff60f
JW
10097\f
10098;;
10099;; MIPS4 Conditional move instructions.
10100
10101(define_insn ""
10102 [(set (match_operand:SI 0 "register_operand" "=d,d")
10103 (if_then_else:SI
10104 (match_operator 4 "equality_op"
10105 [(match_operand:SI 1 "register_operand" "d,d")
10106 (const_int 0)])
10107 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10108 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
0025b7fa 10109 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
e19ff60f
JW
10110 "@
10111 mov%B4\\t%0,%z2,%1
10112 mov%b4\\t%0,%z3,%1"
10113 [(set_attr "type" "move")
10114 (set_attr "mode" "SI")])
10115
197b2bf3
JW
10116(define_insn ""
10117 [(set (match_operand:SI 0 "register_operand" "=d,d")
10118 (if_then_else:SI
10119 (match_operator 4 "equality_op"
cafe096b 10120 [(match_operand:DI 1 "register_operand" "d,d")
197b2bf3
JW
10121 (const_int 0)])
10122 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10123 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
0025b7fa 10124 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
197b2bf3
JW
10125 "@
10126 mov%B4\\t%0,%z2,%1
10127 mov%b4\\t%0,%z3,%1"
10128 [(set_attr "type" "move")
10129 (set_attr "mode" "SI")])
10130
e19ff60f
JW
10131(define_insn ""
10132 [(set (match_operand:SI 0 "register_operand" "=d,d")
10133 (if_then_else:SI
b8eb88d0
ILT
10134 (match_operator 3 "equality_op" [(match_operand:CC 4
10135 "register_operand"
10136 "z,z")
10137 (const_int 0)])
e19ff60f
JW
10138 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10139 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
76ee8042 10140 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f 10141 "@
b8eb88d0
ILT
10142 mov%T3\\t%0,%z1,%4
10143 mov%t3\\t%0,%z2,%4"
e19ff60f
JW
10144 [(set_attr "type" "move")
10145 (set_attr "mode" "SI")])
10146
197b2bf3
JW
10147(define_insn ""
10148 [(set (match_operand:DI 0 "register_operand" "=d,d")
10149 (if_then_else:DI
10150 (match_operator 4 "equality_op"
10151 [(match_operand:SI 1 "register_operand" "d,d")
10152 (const_int 0)])
cafe096b
EC
10153 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
10154 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
d6b6ba29 10155 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
197b2bf3
JW
10156 "@
10157 mov%B4\\t%0,%z2,%1
10158 mov%b4\\t%0,%z3,%1"
10159 [(set_attr "type" "move")
10160 (set_attr "mode" "DI")])
10161
e19ff60f
JW
10162(define_insn ""
10163 [(set (match_operand:DI 0 "register_operand" "=d,d")
10164 (if_then_else:DI
10165 (match_operator 4 "equality_op"
cafe096b 10166 [(match_operand:DI 1 "register_operand" "d,d")
e19ff60f 10167 (const_int 0)])
cafe096b
EC
10168 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
10169 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
d6b6ba29 10170 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
e19ff60f
JW
10171 "@
10172 mov%B4\\t%0,%z2,%1
10173 mov%b4\\t%0,%z3,%1"
10174 [(set_attr "type" "move")
10175 (set_attr "mode" "DI")])
10176
10177(define_insn ""
10178 [(set (match_operand:DI 0 "register_operand" "=d,d")
10179 (if_then_else:DI
b8eb88d0
ILT
10180 (match_operator 3 "equality_op" [(match_operand:CC 4
10181 "register_operand"
10182 "z,z")
10183 (const_int 0)])
cafe096b
EC
10184 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
10185 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
d6b6ba29 10186 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
e19ff60f 10187 "@
b8eb88d0
ILT
10188 mov%T3\\t%0,%z1,%4
10189 mov%t3\\t%0,%z2,%4"
e19ff60f
JW
10190 [(set_attr "type" "move")
10191 (set_attr "mode" "DI")])
10192
10193(define_insn ""
10194 [(set (match_operand:SF 0 "register_operand" "=f,f")
10195 (if_then_else:SF
10196 (match_operator 4 "equality_op"
10197 [(match_operand:SI 1 "register_operand" "d,d")
10198 (const_int 0)])
10199 (match_operand:SF 2 "register_operand" "f,0")
10200 (match_operand:SF 3 "register_operand" "0,f")))]
76ee8042 10201 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f
JW
10202 "@
10203 mov%B4.s\\t%0,%2,%1
10204 mov%b4.s\\t%0,%3,%1"
10205 [(set_attr "type" "move")
10206 (set_attr "mode" "SF")])
10207
b3a79892
MM
10208(define_insn ""
10209 [(set (match_operand:SF 0 "register_operand" "=f,f")
10210 (if_then_else:SF
10211 (match_operator 4 "equality_op"
cafe096b 10212 [(match_operand:DI 1 "register_operand" "d,d")
b3a79892
MM
10213 (const_int 0)])
10214 (match_operand:SF 2 "register_operand" "f,0")
10215 (match_operand:SF 3 "register_operand" "0,f")))]
76ee8042 10216 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
b3a79892
MM
10217 "@
10218 mov%B4.s\\t%0,%2,%1
10219 mov%b4.s\\t%0,%3,%1"
10220 [(set_attr "type" "move")
10221 (set_attr "mode" "SF")])
10222
e19ff60f
JW
10223(define_insn ""
10224 [(set (match_operand:SF 0 "register_operand" "=f,f")
10225 (if_then_else:SF
b8eb88d0
ILT
10226 (match_operator 3 "equality_op" [(match_operand:CC 4
10227 "register_operand"
10228 "z,z")
10229 (const_int 0)])
e19ff60f
JW
10230 (match_operand:SF 1 "register_operand" "f,0")
10231 (match_operand:SF 2 "register_operand" "0,f")))]
76ee8042 10232 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f 10233 "@
b8eb88d0
ILT
10234 mov%T3.s\\t%0,%1,%4
10235 mov%t3.s\\t%0,%2,%4"
e19ff60f
JW
10236 [(set_attr "type" "move")
10237 (set_attr "mode" "SF")])
10238
10239(define_insn ""
10240 [(set (match_operand:DF 0 "register_operand" "=f,f")
10241 (if_then_else:DF
10242 (match_operator 4 "equality_op"
10243 [(match_operand:SI 1 "register_operand" "d,d")
10244 (const_int 0)])
10245 (match_operand:DF 2 "register_operand" "f,0")
10246 (match_operand:DF 3 "register_operand" "0,f")))]
76ee8042 10247 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b3a79892
MM
10248 "@
10249 mov%B4.d\\t%0,%2,%1
10250 mov%b4.d\\t%0,%3,%1"
10251 [(set_attr "type" "move")
10252 (set_attr "mode" "DF")])
10253
10254(define_insn ""
10255 [(set (match_operand:DF 0 "register_operand" "=f,f")
10256 (if_then_else:DF
10257 (match_operator 4 "equality_op"
cafe096b 10258 [(match_operand:DI 1 "register_operand" "d,d")
b3a79892
MM
10259 (const_int 0)])
10260 (match_operand:DF 2 "register_operand" "f,0")
10261 (match_operand:DF 3 "register_operand" "0,f")))]
76ee8042 10262 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f
JW
10263 "@
10264 mov%B4.d\\t%0,%2,%1
10265 mov%b4.d\\t%0,%3,%1"
10266 [(set_attr "type" "move")
10267 (set_attr "mode" "DF")])
10268
10269(define_insn ""
10270 [(set (match_operand:DF 0 "register_operand" "=f,f")
10271 (if_then_else:DF
b8eb88d0
ILT
10272 (match_operator 3 "equality_op" [(match_operand:CC 4
10273 "register_operand"
10274 "z,z")
10275 (const_int 0)])
e19ff60f
JW
10276 (match_operand:DF 1 "register_operand" "f,0")
10277 (match_operand:DF 2 "register_operand" "0,f")))]
76ee8042 10278 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f 10279 "@
b8eb88d0
ILT
10280 mov%T3.d\\t%0,%1,%4
10281 mov%t3.d\\t%0,%2,%4"
e19ff60f
JW
10282 [(set_attr "type" "move")
10283 (set_attr "mode" "DF")])
10284
10285;; These are the main define_expand's used to make conditional moves.
10286
10287(define_expand "movsicc"
10288 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10289 (set (match_operand:SI 0 "register_operand" "")
10290 (if_then_else:SI (match_dup 5)
10291 (match_operand:SI 2 "reg_or_0_operand" "")
10292 (match_operand:SI 3 "reg_or_0_operand" "")))]
0025b7fa 10293 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
e19ff60f
JW
10294 "
10295{
b8eb88d0
ILT
10296 gen_conditional_move (operands);
10297 DONE;
10298}")
e19ff60f 10299
b8eb88d0
ILT
10300(define_expand "movdicc"
10301 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10302 (set (match_operand:DI 0 "register_operand" "")
10303 (if_then_else:DI (match_dup 5)
cafe096b
EC
10304 (match_operand:DI 2 "reg_or_0_operand" "")
10305 (match_operand:DI 3 "reg_or_0_operand" "")))]
d6b6ba29 10306 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
b8eb88d0
ILT
10307 "
10308{
10309 gen_conditional_move (operands);
10310 DONE;
10311}")
e19ff60f 10312
b8eb88d0
ILT
10313(define_expand "movsfcc"
10314 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10315 (set (match_operand:SF 0 "register_operand" "")
10316 (if_then_else:SF (match_dup 5)
91760fce
ILT
10317 (match_operand:SF 2 "register_operand" "")
10318 (match_operand:SF 3 "register_operand" "")))]
76ee8042 10319 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
b8eb88d0
ILT
10320 "
10321{
10322 gen_conditional_move (operands);
10323 DONE;
e19ff60f
JW
10324}")
10325
b8eb88d0
ILT
10326(define_expand "movdfcc"
10327 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10328 (set (match_operand:DF 0 "register_operand" "")
10329 (if_then_else:DF (match_dup 5)
91760fce
ILT
10330 (match_operand:DF 2 "register_operand" "")
10331 (match_operand:DF 3 "register_operand" "")))]
76ee8042 10332 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
10333 "
10334{
10335 gen_conditional_move (operands);
10336 DONE;
10337}")
2bcb2ab3
GK
10338\f
10339;;
10340;; ....................
10341;;
10342;; mips16 inline constant tables
10343;;
10344;; ....................
10345;;
10346
10347(define_insn "consttable_qi"
41f8d041
RS
10348 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
10349 UNSPEC_CONSTTABLE_QI)]
2bcb2ab3
GK
10350 "TARGET_MIPS16"
10351 "*
10352{
c8af3574 10353 assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
2bcb2ab3
GK
10354 return \"\";
10355}"
10356 [(set_attr "type" "unknown")
10357 (set_attr "mode" "QI")
0ff83799 10358 (set_attr "length" "8")])
2bcb2ab3
GK
10359
10360(define_insn "consttable_hi"
41f8d041
RS
10361 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
10362 UNSPEC_CONSTTABLE_HI)]
2bcb2ab3
GK
10363 "TARGET_MIPS16"
10364 "*
10365{
c8af3574 10366 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
2bcb2ab3
GK
10367 return \"\";
10368}"
10369 [(set_attr "type" "unknown")
10370 (set_attr "mode" "HI")
0ff83799 10371 (set_attr "length" "8")])
2bcb2ab3
GK
10372
10373(define_insn "consttable_si"
41f8d041
RS
10374 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
10375 UNSPEC_CONSTTABLE_SI)]
2bcb2ab3
GK
10376 "TARGET_MIPS16"
10377 "*
10378{
c8af3574 10379 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
2bcb2ab3
GK
10380 return \"\";
10381}"
10382 [(set_attr "type" "unknown")
10383 (set_attr "mode" "SI")
0ff83799 10384 (set_attr "length" "8")])
2bcb2ab3
GK
10385
10386(define_insn "consttable_di"
41f8d041
RS
10387 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
10388 UNSPEC_CONSTTABLE_DI)]
2bcb2ab3
GK
10389 "TARGET_MIPS16"
10390 "*
10391{
c8af3574 10392 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
2bcb2ab3
GK
10393 return \"\";
10394}"
10395 [(set_attr "type" "unknown")
10396 (set_attr "mode" "DI")
0ff83799 10397 (set_attr "length" "16")])
2bcb2ab3
GK
10398
10399(define_insn "consttable_sf"
41f8d041
RS
10400 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
10401 UNSPEC_CONSTTABLE_SF)]
2bcb2ab3
GK
10402 "TARGET_MIPS16"
10403 "*
10404{
81b4c798 10405 REAL_VALUE_TYPE d;
2bcb2ab3
GK
10406
10407 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10408 abort ();
81b4c798
ZW
10409 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10410 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
2bcb2ab3
GK
10411 return \"\";
10412}"
10413 [(set_attr "type" "unknown")
10414 (set_attr "mode" "SF")
0ff83799 10415 (set_attr "length" "8")])
2bcb2ab3
GK
10416
10417(define_insn "consttable_df"
41f8d041
RS
10418 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
10419 UNSPEC_CONSTTABLE_DF)]
2bcb2ab3
GK
10420 "TARGET_MIPS16"
10421 "*
10422{
81b4c798 10423 REAL_VALUE_TYPE d;
2bcb2ab3
GK
10424
10425 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10426 abort ();
81b4c798
ZW
10427 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10428 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
2bcb2ab3
GK
10429 return \"\";
10430}"
10431 [(set_attr "type" "unknown")
10432 (set_attr "mode" "DF")
0ff83799 10433 (set_attr "length" "16")])
2bcb2ab3
GK
10434
10435(define_insn "align_2"
41f8d041 10436 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
2bcb2ab3
GK
10437 "TARGET_MIPS16"
10438 ".align 1"
10439 [(set_attr "type" "unknown")
10440 (set_attr "mode" "HI")
0ff83799 10441 (set_attr "length" "8")])
2bcb2ab3
GK
10442
10443(define_insn "align_4"
41f8d041 10444 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
2bcb2ab3
GK
10445 "TARGET_MIPS16"
10446 ".align 2"
10447 [(set_attr "type" "unknown")
10448 (set_attr "mode" "SI")
0ff83799 10449 (set_attr "length" "8")])
2bcb2ab3
GK
10450
10451(define_insn "align_8"
41f8d041 10452 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
2bcb2ab3
GK
10453 "TARGET_MIPS16"
10454 ".align 3"
10455 [(set_attr "type" "unknown")
10456 (set_attr "mode" "DI")
0ff83799 10457 (set_attr "length" "12")])
2bcb2ab3
GK
10458\f
10459;;
10460;; ....................
10461;;
10462;; mips16 peepholes
10463;;
10464;; ....................
10465;;
10466
10467;; On the mips16, reload will sometimes decide that a pseudo register
10468;; should go into $24, and then later on have to reload that register.
10469;; When that happens, we get a load of a general register followed by
10470;; a move from the general register to $24 followed by a branch.
10471;; These peepholes catch the common case, and fix it to just use the
10472;; general register for the branch.
10473
10474(define_peephole
10475 [(set (match_operand:SI 0 "register_operand" "=t")
10476 (match_operand:SI 1 "register_operand" "d"))
10477 (set (pc)
10478 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10479 (const_int 0)])
10480 (match_operand 3 "pc_or_label_operand" "")
10481 (match_operand 4 "pc_or_label_operand" "")))]
10482 "TARGET_MIPS16
10483 && GET_CODE (operands[0]) == REG
10484 && REGNO (operands[0]) == 24
10485 && dead_or_set_p (insn, operands[0])
10486 && GET_CODE (operands[1]) == REG
10487 && M16_REG_P (REGNO (operands[1]))"
10488 "*
10489{
10490 if (operands[3] != pc_rtx)
10491 return \"%*b%C2z\\t%1,%3\";
10492 else
10493 return \"%*b%N2z\\t%1,%4\";
10494}"
10495 [(set_attr "type" "branch")
10496 (set_attr "mode" "none")
0ff83799 10497 (set_attr "length" "8")])
2bcb2ab3
GK
10498
10499(define_peephole
10500 [(set (match_operand:DI 0 "register_operand" "=t")
10501 (match_operand:DI 1 "register_operand" "d"))
10502 (set (pc)
10503 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10504 (const_int 0)])
10505 (match_operand 3 "pc_or_label_operand" "")
10506 (match_operand 4 "pc_or_label_operand" "")))]
10507 "TARGET_MIPS16 && TARGET_64BIT
10508 && GET_CODE (operands[0]) == REG
10509 && REGNO (operands[0]) == 24
10510 && dead_or_set_p (insn, operands[0])
10511 && GET_CODE (operands[1]) == REG
10512 && M16_REG_P (REGNO (operands[1]))"
10513 "*
10514{
10515 if (operands[3] != pc_rtx)
10516 return \"%*b%C2z\\t%1,%3\";
10517 else
10518 return \"%*b%N2z\\t%1,%4\";
10519}"
10520 [(set_attr "type" "branch")
10521 (set_attr "mode" "none")
0ff83799 10522 (set_attr "length" "8")])
2bcb2ab3
GK
10523
10524;; We can also have the reverse reload: reload will spill $24 into
10525;; another register, and then do a branch on that register when it
10526;; could have just stuck with $24.
10527
10528(define_peephole
10529 [(set (match_operand:SI 0 "register_operand" "=d")
10530 (match_operand:SI 1 "register_operand" "t"))
10531 (set (pc)
10532 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10533 (const_int 0)])
10534 (match_operand 3 "pc_or_label_operand" "")
10535 (match_operand 4 "pc_or_label_operand" "")))]
10536 "TARGET_MIPS16
10537 && GET_CODE (operands[1]) == REG
10538 && REGNO (operands[1]) == 24
10539 && GET_CODE (operands[0]) == REG
10540 && M16_REG_P (REGNO (operands[0]))
10541 && dead_or_set_p (insn, operands[0])"
10542 "*
10543{
10544 if (operands[3] != pc_rtx)
10545 return \"%*bt%C2z\\t%3\";
10546 else
10547 return \"%*bt%N2z\\t%4\";
10548}"
10549 [(set_attr "type" "branch")
10550 (set_attr "mode" "none")
0ff83799 10551 (set_attr "length" "8")])
2bcb2ab3
GK
10552
10553(define_peephole
10554 [(set (match_operand:DI 0 "register_operand" "=d")
10555 (match_operand:DI 1 "register_operand" "t"))
10556 (set (pc)
10557 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10558 (const_int 0)])
10559 (match_operand 3 "pc_or_label_operand" "")
10560 (match_operand 4 "pc_or_label_operand" "")))]
10561 "TARGET_MIPS16 && TARGET_64BIT
10562 && GET_CODE (operands[1]) == REG
10563 && REGNO (operands[1]) == 24
10564 && GET_CODE (operands[0]) == REG
10565 && M16_REG_P (REGNO (operands[0]))
10566 && dead_or_set_p (insn, operands[0])"
10567 "*
10568{
10569 if (operands[3] != pc_rtx)
10570 return \"%*bt%C2z\\t%3\";
10571 else
10572 return \"%*bt%N2z\\t%4\";
10573}"
10574 [(set_attr "type" "branch")
10575 (set_attr "mode" "none")
0ff83799 10576 (set_attr "length" "8")])