]> gcc.gnu.org Git - gcc.git/blame - gcc/config/mips/mips.md
Use byte offsets in SUBREGs instead of words.
[gcc.git] / gcc / config / mips / mips.md
CommitLineData
8ef30996 1;; Mips.md Machine Description for MIPS based processors
214be03f
JL
2;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3;; 1999, 2000 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
8ef30996
MM
29\f
30
31;; ....................
32;;
33;; Attributes
34;;
35;; ....................
36
37;; Classification of each insn.
38;; branch conditional branch
39;; jump unconditional jump
40;; call unconditional call
41;; load load instruction(s)
42;; store store instruction(s)
43;; move data movement within same register set
44;; xfer transfer to/from coprocessor
45;; hilo transfer of hi/lo registers
46;; arith integer arithmetic instruction
47;; darith double precision integer arithmetic instructions
48;; imul integer multiply
49;; idiv integer divide
50;; icmp integer compare
51;; fadd floating point add/subtract
52;; fmul floating point multiply
e19ff60f 53;; fmadd floating point multiply-add
8ef30996
MM
54;; fdiv floating point divide
55;; fabs floating point absolute value
56;; fneg floating point negation
57;; fcmp floating point compare
58;; fcvt floating point convert
59;; fsqrt floating point square root
60;; multi multiword sequence (or user asm statements)
61;; nop no operation
8ef30996
MM
62
63(define_attr "type"
e19ff60f 64 "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
8ef30996
MM
65 (const_string "unknown"))
66
67;; Main data type used by the insn
34b650b3 68(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
8ef30996 69
0ff83799
MM
70;; Length (in # of bytes). A conditional branch is allowed only to a
71;; location within a signed 18-bit offset of the delay slot. If that
72;; provides too smal a range, we use the `j' instruction. This
73;; instruction takes a 28-bit value, but that value is not an offset.
74;; Instead, it's bitwise-ored with the high-order four bits of the
75;; instruction in the delay slot, which means it cannot be used to
76;; cross a 256MB boundary. We could fall back back on the jr,
77;; instruction which allows full access to the entire address space,
78;; but we do not do so at present.
79
80(define_attr "length" ""
81 (cond [(eq_attr "type" "branch")
82 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
83 (const_int 131072))
84 (const_int 4)]
85 (const_int 12))]
86 (const_int 4)))
8ef30996 87
ddd8ab48
MM
88;; Attribute describing the processor. This attribute must match exactly
89;; with the processor_type enumeration in mips.h.
90
8ef30996 91;; Attribute describing the processor
ddd8ab48
MM
92;; (define_attr "cpu" "default,r3000,r6000,r4000"
93;; (const
94;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
95;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
96;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
97;; (const_string "default"))))
98
e19ff60f 99;; ??? Fix everything that tests this attribute.
b8eb88d0 100(define_attr "cpu"
e9a25f70 101 "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
ddd8ab48 102 (const (symbol_ref "mips_cpu_attr")))
8ef30996 103
ec350bdd 104;; Does the instruction have a mandatory delay slot?
0ff83799 105;; The 3900, is (mostly) mips1, but does not have a mandatory load delay
ec350bdd
GK
106;; slot.
107(define_attr "dslot" "no,yes"
108 (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
109 (and (eq_attr "type" "load")
110 (and (eq (symbol_ref "mips_isa") (const_int 1))
111 (and (eq (symbol_ref "mips16") (const_int 0))
112 (eq_attr "cpu" "!r3900")))))
113 (const_string "yes")
114 (const_string "no")))
115
8ef30996 116;; Attribute defining whether or not we can use the branch-likely instructions
8ef30996
MM
117
118(define_attr "branch_likely" "no,yes"
6d518002 119 (const
e9a25f70 120 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
8ef30996 121 (const_string "yes")
6d518002 122 (const_string "no"))))
8ef30996
MM
123
124
125;; Describe a user's asm statement.
126(define_asm_attributes
127 [(set_attr "type" "multi")])
128
84a92af4
JW
129;; whether or not generating calls to position independent functions
130(define_attr "abicalls" "no,yes"
e0a4e5a5 131 (const (symbol_ref "mips_abicalls_attr")))
84a92af4 132
8ef30996
MM
133\f
134
135;; .........................
136;;
137;; Delay slots, can't describe load/fcmp/xfer delay slots here
138;;
139;; .........................
140
2bcb2ab3
GK
141(define_delay (and (eq_attr "type" "branch")
142 (eq (symbol_ref "mips16") (const_int 0)))
0ff83799 143 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
8ef30996 144 (nil)
0ff83799 145 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])
8ef30996 146
84a92af4 147(define_delay (eq_attr "type" "jump")
0ff83799 148 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
84a92af4
JW
149 (nil)
150 (nil)])
151
152(define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
0ff83799 153 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
8ef30996
MM
154 (nil)
155 (nil)])
156
157\f
158
159;; .........................
160;;
161;; Functional units
162;;
163;; .........................
164
165; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
c8e18a2b 166; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
8ef30996
MM
167
168;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
169
170(define_function_unit "memory" 1 0
b8eb88d0 171 (and (eq_attr "type" "load")
e9a25f70 172 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
8ef30996
MM
173 3 0)
174
175(define_function_unit "memory" 1 0
b8eb88d0 176 (and (eq_attr "type" "load")
e9a25f70 177 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
8ef30996
MM
178 2 0)
179
ddd8ab48 180(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
8ef30996 181
c3f3d7e1 182(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
8ef30996 183
bb621ad7
JW
184(define_function_unit "imuldiv" 1 0
185 (eq_attr "type" "hilo")
186 1 3)
187
188(define_function_unit "imuldiv" 1 0
b8eb88d0 189 (and (eq_attr "type" "imul")
e9a25f70 190 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
bb621ad7 191 17 17)
8ef30996 192
2bcb2ab3
GK
193;; On them mips16, we want to stronly discourage a mult from appearing
194;; after an mflo, since that requires explicit nop instructions. We
195;; do this by pretending that mflo ties up the function unit for long
196;; enough that the scheduler will ignore load stalls and the like when
197;; selecting instructions to between the two instructions.
198
199(define_function_unit "imuldiv" 1 0
200 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
201 1 5)
202
bb621ad7 203(define_function_unit "imuldiv" 1 0
e9a25f70 204 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
bb621ad7 205 12 12)
8ef30996 206
bb621ad7
JW
207(define_function_unit "imuldiv" 1 0
208 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
209 10 10)
8ef30996 210
bb621ad7 211(define_function_unit "imuldiv" 1 0
053665d7
ILT
212 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
213 4 4)
214
215(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
216 (and (eq_attr "type" "imul")
217 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
8fbaea49
JW
218 1 1)
219
220(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
221 (and (eq_attr "type" "imul")
222 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
8fbaea49
JW
223 4 4)
224
225(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
226 (and (eq_attr "type" "imul")
227 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
8fbaea49
JW
228 5 5)
229
230(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
231 (and (eq_attr "type" "imul")
232 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
8fbaea49
JW
233 8 8)
234
235(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
236 (and (eq_attr "type" "imul")
237 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
238 9 9)
239
240(define_function_unit "imuldiv" 1 0
241 (and (eq_attr "type" "idiv")
e9a25f70 242 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
bb621ad7 243 38 38)
8ef30996 244
bb621ad7 245(define_function_unit "imuldiv" 1 0
e9a25f70 246 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
bb621ad7
JW
247 35 35)
248
249(define_function_unit "imuldiv" 1 0
250 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
251 42 42)
8ef30996 252
053665d7
ILT
253(define_function_unit "imuldiv" 1 0
254 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
255 36 36)
256
bb621ad7 257(define_function_unit "imuldiv" 1 0
8ef30996 258 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
bb621ad7
JW
259 69 69)
260
8fbaea49 261(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
262 (and (eq_attr "type" "idiv")
263 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
8fbaea49
JW
264 35 35)
265
266(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
267 (and (eq_attr "type" "idiv")
268 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
8fbaea49
JW
269 67 67)
270
271(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
272 (and (eq_attr "type" "idiv")
273 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
8fbaea49
JW
274 37 37)
275
276(define_function_unit "imuldiv" 1 0
b8eb88d0
ILT
277 (and (eq_attr "type" "idiv")
278 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
8fbaea49
JW
279 69 69)
280
b8eb88d0
ILT
281(define_function_unit "imuldiv" 1 0
282 (and (eq_attr "type" "idiv")
283 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
284 36 36)
285
286(define_function_unit "imuldiv" 1 0
287 (and (eq_attr "type" "idiv")
288 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
289 68 68)
290
956d6950 291;; The R4300 does *NOT* have a separate Floating Point Unit, instead
8fbaea49
JW
292;; the FP hardware is part of the normal ALU circuitry. This means FP
293;; instructions affect the pipe-line, and no functional unit
294;; parallelism can occur on R4300 processors. To force GCC into coding
295;; for only a single functional unit, we force the R4300 FP
296;; instructions to be processed in the "imuldiv" unit.
297
bb621ad7 298(define_function_unit "adder" 1 1
e9a25f70 299 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
bb621ad7
JW
300 3 0)
301
302(define_function_unit "adder" 1 1
e9a25f70 303 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
bb621ad7 304 2 0)
8ef30996 305
b8eb88d0
ILT
306(define_function_unit "adder" 1 1
307 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
308 1 0)
309
8ef30996 310(define_function_unit "adder" 1 1
e9a25f70 311 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
c8e18a2b 312 4 0)
8ef30996
MM
313
314(define_function_unit "adder" 1 1
e9a25f70 315 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
c8e18a2b 316 2 0)
8ef30996
MM
317
318(define_function_unit "adder" 1 1
319 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
c8e18a2b 320 3 0)
8ef30996 321
ddd8ab48 322(define_function_unit "adder" 1 1
b8eb88d0 323 (and (eq_attr "type" "fabs,fneg")
e9a25f70 324 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
c8e18a2b 325 2 0)
8ef30996 326
ddd8ab48 327(define_function_unit "adder" 1 1
e9a25f70 328 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
c8e18a2b 329 1 0)
8ef30996
MM
330
331(define_function_unit "mult" 1 1
b8eb88d0
ILT
332 (and (eq_attr "type" "fmul")
333 (and (eq_attr "mode" "SF")
e9a25f70 334 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
c8e18a2b 335 7 0)
8ef30996
MM
336
337(define_function_unit "mult" 1 1
b8eb88d0 338 (and (eq_attr "type" "fmul")
e9a25f70 339 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
c8e18a2b 340 4 0)
8ef30996
MM
341
342(define_function_unit "mult" 1 1
b8eb88d0
ILT
343 (and (eq_attr "type" "fmul")
344 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
c8e18a2b 345 5 0)
8ef30996 346
bb621ad7 347(define_function_unit "mult" 1 1
b8eb88d0
ILT
348 (and (eq_attr "type" "fmul")
349 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
350 8 0)
351
8ef30996 352(define_function_unit "mult" 1 1
b8eb88d0 353 (and (eq_attr "type" "fmul")
e9a25f70 354 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
c8e18a2b 355 8 0)
8ef30996
MM
356
357(define_function_unit "mult" 1 1
b8eb88d0 358 (and (eq_attr "type" "fmul")
e9a25f70 359 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
c8e18a2b 360 5 0)
8ef30996
MM
361
362(define_function_unit "mult" 1 1
b8eb88d0
ILT
363 (and (eq_attr "type" "fmul")
364 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
c8e18a2b 365 6 0)
8ef30996
MM
366
367(define_function_unit "divide" 1 1
b8eb88d0
ILT
368 (and (eq_attr "type" "fdiv")
369 (and (eq_attr "mode" "SF")
e9a25f70 370 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
c8e18a2b 371 23 0)
8ef30996
MM
372
373(define_function_unit "divide" 1 1
b8eb88d0 374 (and (eq_attr "type" "fdiv")
e9a25f70 375 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
c8e18a2b 376 12 0)
8ef30996
MM
377
378(define_function_unit "divide" 1 1
b8eb88d0
ILT
379 (and (eq_attr "type" "fdiv")
380 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
c8e18a2b 381 15 0)
8ef30996
MM
382
383(define_function_unit "divide" 1 1
b8eb88d0
ILT
384 (and (eq_attr "type" "fdiv")
385 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
386 32 0)
387
388(define_function_unit "divide" 1 1
b8eb88d0
ILT
389 (and (eq_attr "type" "fdiv")
390 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
391 21 0)
392
393(define_function_unit "divide" 1 1
394 (and (eq_attr "type" "fdiv")
395 (and (eq_attr "mode" "DF")
e9a25f70 396 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
c8e18a2b 397 36 0)
8ef30996
MM
398
399(define_function_unit "divide" 1 1
b8eb88d0 400 (and (eq_attr "type" "fdiv")
e9a25f70 401 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
c8e18a2b 402 19 0)
8ef30996
MM
403
404(define_function_unit "divide" 1 1
b8eb88d0
ILT
405 (and (eq_attr "type" "fdiv")
406 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
c8e18a2b 407 16 0)
8ef30996 408
bb621ad7 409(define_function_unit "divide" 1 1
b8eb88d0
ILT
410 (and (eq_attr "type" "fdiv")
411 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
412 61 0)
413
414;;; ??? Is this number right?
415(define_function_unit "divide" 1 1
b8eb88d0
ILT
416 (and (eq_attr "type" "fsqrt")
417 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
bb621ad7 418 54 0)
b8eb88d0 419
bb621ad7 420(define_function_unit "divide" 1 1
b8eb88d0
ILT
421 (and (eq_attr "type" "fsqrt")
422 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7
JW
423 31 0)
424
b8eb88d0
ILT
425(define_function_unit "divide" 1 1
426 (and (eq_attr "type" "fsqrt")
427 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
428 21 0)
429
bb621ad7
JW
430;;; ??? Is this number right?
431(define_function_unit "divide" 1 1
b8eb88d0
ILT
432 (and (eq_attr "type" "fsqrt")
433 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
bb621ad7 434 112 0)
b8eb88d0 435
bb621ad7 436(define_function_unit "divide" 1 1
b8eb88d0
ILT
437 (and (eq_attr "type" "fsqrt")
438 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
bb621ad7 439 60 0)
8ef30996 440
b8eb88d0
ILT
441(define_function_unit "divide" 1 1
442 (and (eq_attr "type" "fsqrt")
443 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
444 36 0)
445
8fbaea49
JW
446;; R4300 FP instruction classes treated as part of the "imuldiv"
447;; functional unit:
448
449(define_function_unit "imuldiv" 1 0
450 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
451 3 3)
452
aa4e54c4
JW
453(define_function_unit "imuldiv" 1 0
454 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
455 1 1)
456
8fbaea49
JW
457(define_function_unit "imuldiv" 1 0
458 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
459 5 5)
460(define_function_unit "imuldiv" 1 0
461 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
462 8 8)
463
464(define_function_unit "imuldiv" 1 0
465 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
466 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
467 29 29)
468(define_function_unit "imuldiv" 1 0
469 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
470 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
471 58 58)
ddd8ab48
MM
472\f
473;; The following functional units do not use the cpu type, and use
474;; much less memory in genattrtab.c.
475
c8e18a2b
TW
476;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
477;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
ddd8ab48 478;;
c8e18a2b 479;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
ddd8ab48 480;;
c8e18a2b
TW
481;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
482;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
ddd8ab48 483;;
c8e18a2b
TW
484;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
485;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
ddd8ab48 486;;
c8e18a2b
TW
487;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
488;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
ddd8ab48 489;;
c8e18a2b
TW
490;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
491;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
ddd8ab48 492;;
c8e18a2b
TW
493;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
494;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
ddd8ab48 495;;
c8e18a2b
TW
496;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
497;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
a0b6cdee
GM
498\f
499;;
500;; ....................
501;;
502;; CONDITIONAL TRAPS
503;;
504;; ....................
505;;
ddd8ab48 506
a0b6cdee
GM
507(define_insn "trap"
508 [(trap_if (const_int 1) (const_int 0))]
509 ""
510 "*
511{
512 if (ISA_HAS_COND_TRAP)
513 return \"teq\\t$0,$0\";
514 else
515 return \"break\";
516}")
517
518(define_expand "conditional_trap"
519 [(trap_if (match_operator 0 "cmp_op"
520 [(match_dup 2) (match_dup 3)])
521 (match_operand 1 "const_int_operand" ""))]
522 "ISA_HAS_COND_TRAP"
523 "
524{
525 mips_gen_conditional_trap (operands);
526 DONE;
527}")
528
529;; Match a TRAP_IF with 2nd arg of 0. The div_trap_* insns match a
530;; 2nd arg of any CONST_INT, so this insn must appear first.
531;; gen_div_trap always generates TRAP_IF with 2nd arg of 6 or 7.
532
533(define_insn ""
534 [(trap_if (match_operator 0 "trap_cmp_op"
535 [(match_operand:SI 1 "reg_or_0_operand" "d")
536 (match_operand:SI 2 "nonmemory_operand" "dI")])
537 (const_int 0))]
538 "ISA_HAS_COND_TRAP"
539 "t%C0\\t%z1,%z2")
8ef30996
MM
540\f
541;;
542;; ....................
543;;
544;; ADDITION
545;;
546;; ....................
547;;
548
549(define_insn "adddf3"
550 [(set (match_operand:DF 0 "register_operand" "=f")
551 (plus:DF (match_operand:DF 1 "register_operand" "f")
552 (match_operand:DF 2 "register_operand" "f")))]
46299de9 553 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
554 "add.d\\t%0,%1,%2"
555 [(set_attr "type" "fadd")
0ff83799 556 (set_attr "mode" "DF")])
8ef30996
MM
557
558(define_insn "addsf3"
559 [(set (match_operand:SF 0 "register_operand" "=f")
560 (plus:SF (match_operand:SF 1 "register_operand" "f")
561 (match_operand:SF 2 "register_operand" "f")))]
562 "TARGET_HARD_FLOAT"
563 "add.s\\t%0,%1,%2"
564 [(set_attr "type" "fadd")
0ff83799 565 (set_attr "mode" "SF")])
8ef30996 566
71cd5224 567(define_expand "addsi3"
8ef30996 568 [(set (match_operand:SI 0 "register_operand" "=d")
71cd5224 569 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
8ef30996
MM
570 (match_operand:SI 2 "arith_operand" "dI")))]
571 ""
71cd5224
RS
572 "
573{
2bcb2ab3
GK
574 /* The mips16 assembler handles -32768 correctly, and so does gas,
575 but some other MIPS assemblers think that -32768 needs to be
576 loaded into a register before it can be added in. */
577 if (! TARGET_MIPS16
578 && ! TARGET_GAS
579 && GET_CODE (operands[2]) == CONST_INT
580 && INTVAL (operands[2]) == -32768)
71cd5224
RS
581 operands[2] = force_reg (SImode, operands[2]);
582}")
583
584(define_insn "addsi3_internal"
585 [(set (match_operand:SI 0 "register_operand" "=d")
586 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
587 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3
GK
588 "! TARGET_MIPS16
589 && (TARGET_GAS
590 || GET_CODE (operands[2]) != CONST_INT
591 || INTVAL (operands[2]) != -32768)"
9b190d1c 592 "addu\\t%0,%z1,%2"
8ef30996 593 [(set_attr "type" "arith")
0ff83799 594 (set_attr "mode" "SI")])
8ef30996 595
2bcb2ab3
GK
596;; For the mips16, we need to recognize stack pointer additions
597;; explicitly, since we don't have a constraint for $sp. These insns
598;; will be generated by the save_restore_insns functions.
599
600(define_insn ""
601 [(set (reg:SI 29)
602 (plus:SI (reg:SI 29)
603 (match_operand:SI 0 "small_int" "I")))]
604 "TARGET_MIPS16"
605 "addu\\t%$,%$,%0"
606 [(set_attr "type" "arith")
607 (set_attr "mode" "SI")
608 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
0ff83799
MM
609 (const_int 4)
610 (const_int 8)))])
2bcb2ab3
GK
611
612(define_insn ""
613 [(set (match_operand:SI 0 "register_operand" "=d")
614 (plus:SI (reg:SI 29)
615 (match_operand:SI 1 "small_int" "I")))]
616 "TARGET_MIPS16"
617 "addu\\t%0,%$,%1"
618 [(set_attr "type" "arith")
619 (set_attr "mode" "SI")
620 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
0ff83799
MM
621 (const_int 4)
622 (const_int 8)))])
2bcb2ab3
GK
623
624(define_insn ""
625 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
626 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
627 (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
628 "TARGET_MIPS16
629 && (GET_CODE (operands[1]) != REG
630 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
631 || M16_REG_P (REGNO (operands[1]))
632 || REGNO (operands[1]) == ARG_POINTER_REGNUM
633 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
634 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
635 && (GET_CODE (operands[2]) != REG
636 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
637 || M16_REG_P (REGNO (operands[2]))
638 || REGNO (operands[2]) == ARG_POINTER_REGNUM
639 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
640 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
641 "*
642{
643 if (REGNO (operands[0]) == REGNO (operands[1]))
644 return \"addu\\t%0,%2\";
645 return \"addu\\t%0,%1,%2\";
646}"
647 [(set_attr "type" "arith")
648 (set_attr "mode" "SI")
649 (set_attr_alternative "length"
650 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
0ff83799
MM
651 (const_int 4)
652 (const_int 8))
2bcb2ab3 653 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
0ff83799
MM
654 (const_int 4)
655 (const_int 8))
656 (const_int 4)])])
2bcb2ab3
GK
657
658
659;; On the mips16, we can sometimes split an add of a constant which is
660;; a 4 byte instruction into two adds which are both 2 byte
661;; instructions. There are two cases: one where we are adding a
662;; constant plus a register to another register, and one where we are
663;; simply adding a constant to a register.
664
665(define_split
666 [(set (match_operand:SI 0 "register_operand" "")
667 (plus:SI (match_dup 0)
668 (match_operand:SI 1 "const_int_operand" "")))]
669 "TARGET_MIPS16 && reload_completed
670 && GET_CODE (operands[0]) == REG
671 && M16_REG_P (REGNO (operands[0]))
672 && GET_CODE (operands[1]) == CONST_INT
673 && ((INTVAL (operands[1]) > 0x7f
674 && INTVAL (operands[1]) <= 0x7f + 0x7f)
675 || (INTVAL (operands[1]) < - 0x80
676 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
677 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
678 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
679 "
680{
681 HOST_WIDE_INT val = INTVAL (operands[1]);
682
683 if (val >= 0)
684 {
685 operands[1] = GEN_INT (0x7f);
686 operands[2] = GEN_INT (val - 0x7f);
687 }
688 else
689 {
690 operands[1] = GEN_INT (- 0x80);
691 operands[2] = GEN_INT (val + 0x80);
692 }
693}")
694
695(define_split
696 [(set (match_operand:SI 0 "register_operand" "")
697 (plus:SI (match_operand:SI 1 "register_operand" "")
698 (match_operand:SI 2 "const_int_operand" "")))]
699 "TARGET_MIPS16 && reload_completed
700 && GET_CODE (operands[0]) == REG
701 && M16_REG_P (REGNO (operands[0]))
702 && GET_CODE (operands[1]) == REG
703 && M16_REG_P (REGNO (operands[1]))
704 && REGNO (operands[0]) != REGNO (operands[1])
705 && GET_CODE (operands[2]) == CONST_INT
706 && ((INTVAL (operands[2]) > 0x7
707 && INTVAL (operands[2]) <= 0x7 + 0x7f)
708 || (INTVAL (operands[2]) < - 0x8
709 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
710 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
711 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
712 "
713{
714 HOST_WIDE_INT val = INTVAL (operands[2]);
715
716 if (val >= 0)
717 {
718 operands[2] = GEN_INT (0x7);
719 operands[3] = GEN_INT (val - 0x7);
720 }
721 else
722 {
723 operands[2] = GEN_INT (- 0x8);
724 operands[3] = GEN_INT (val + 0x8);
725 }
726}")
727
8ef30996
MM
728(define_expand "adddi3"
729 [(parallel [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
730 (plus:DI (match_operand:DI 1 "se_register_operand" "")
731 (match_operand:DI 2 "se_arith_operand" "")))
8ef30996 732 (clobber (match_dup 3))])]
2bcb2ab3 733 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
92b4cee1
MM
734 "
735{
2bcb2ab3
GK
736 /* The mips16 assembler handles -32768 correctly, and so does gas,
737 but some other MIPS assemblers think that -32768 needs to be
738 loaded into a register before it can be added in. */
739 if (! TARGET_MIPS16
740 && ! TARGET_GAS
741 && GET_CODE (operands[2]) == CONST_INT
742 && INTVAL (operands[2]) == -32768)
b0565769 743 operands[2] = force_reg (DImode, operands[2]);
92b4cee1 744
bb621ad7
JW
745 if (TARGET_64BIT)
746 {
747 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
748 operands[2]));
749 DONE;
750 }
751
92b4cee1
MM
752 operands[3] = gen_reg_rtx (SImode);
753}")
8ef30996
MM
754
755(define_insn "adddi3_internal_1"
756 [(set (match_operand:DI 0 "register_operand" "=d,&d")
757 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
758 (match_operand:DI 2 "register_operand" "d,d")))
759 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
2bcb2ab3 760 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
761 "*
762{
763 return (REGNO (operands[0]) == REGNO (operands[1])
764 && REGNO (operands[0]) == REGNO (operands[2]))
765 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
766 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
767}"
92b4cee1
MM
768 [(set_attr "type" "darith")
769 (set_attr "mode" "DI")
0ff83799 770 (set_attr "length" "16")])
8ef30996
MM
771
772(define_split
773 [(set (match_operand:DI 0 "register_operand" "")
774 (plus:DI (match_operand:DI 1 "register_operand" "")
775 (match_operand:DI 2 "register_operand" "")))
776 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
777 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
778 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
779 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
780 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
781 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
782 && (REGNO (operands[0]) != REGNO (operands[1])
783 || REGNO (operands[0]) != REGNO (operands[2]))"
784
785 [(set (subreg:SI (match_dup 0) 0)
786 (plus:SI (subreg:SI (match_dup 1) 0)
787 (subreg:SI (match_dup 2) 0)))
788
789 (set (match_dup 3)
34b650b3 790 (ltu:SI (subreg:SI (match_dup 0) 0)
8ef30996
MM
791 (subreg:SI (match_dup 2) 0)))
792
ddef6bc7
JJ
793 (set (subreg:SI (match_dup 0) 4)
794 (plus:SI (subreg:SI (match_dup 1) 4)
795 (subreg:SI (match_dup 2) 4)))
8ef30996 796
ddef6bc7
JJ
797 (set (subreg:SI (match_dup 0) 4)
798 (plus:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
799 (match_dup 3)))]
800 "")
801
802(define_split
803 [(set (match_operand:DI 0 "register_operand" "")
804 (plus:DI (match_operand:DI 1 "register_operand" "")
805 (match_operand:DI 2 "register_operand" "")))
806 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
807 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
808 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
809 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
810 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
811 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
812 && (REGNO (operands[0]) != REGNO (operands[1])
813 || REGNO (operands[0]) != REGNO (operands[2]))"
814
ddef6bc7
JJ
815 [(set (subreg:SI (match_dup 0) 4)
816 (plus:SI (subreg:SI (match_dup 1) 4)
817 (subreg:SI (match_dup 2) 4)))
8ef30996
MM
818
819 (set (match_dup 3)
ddef6bc7
JJ
820 (ltu:SI (subreg:SI (match_dup 0) 4)
821 (subreg:SI (match_dup 2) 4)))
8ef30996
MM
822
823 (set (subreg:SI (match_dup 0) 0)
824 (plus:SI (subreg:SI (match_dup 1) 0)
825 (subreg:SI (match_dup 2) 0)))
826
827 (set (subreg:SI (match_dup 0) 0)
828 (plus:SI (subreg:SI (match_dup 0) 0)
829 (match_dup 3)))]
830 "")
831
832(define_insn "adddi3_internal_2"
833 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
834 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
835 (match_operand:DI 2 "small_int" "P,J,N")))
836 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
2bcb2ab3 837 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
82301b88
JL
838 && (TARGET_GAS
839 || GET_CODE (operands[2]) != CONST_INT
840 || INTVAL (operands[2]) != -32768)"
8ef30996
MM
841 "@
842 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
843 move\\t%L0,%L1\;move\\t%M0,%M1
844 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
92b4cee1
MM
845 [(set_attr "type" "darith")
846 (set_attr "mode" "DI")
0ff83799 847 (set_attr "length" "12,8,16")])
8ef30996
MM
848
849(define_split
850 [(set (match_operand:DI 0 "register_operand" "")
851 (plus:DI (match_operand:DI 1 "register_operand" "")
852 (match_operand:DI 2 "small_int" "")))
853 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3
GK
854 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
855 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
856 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
857 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
858 && INTVAL (operands[2]) > 0"
859
860 [(set (subreg:SI (match_dup 0) 0)
861 (plus:SI (subreg:SI (match_dup 1) 0)
862 (match_dup 2)))
863
864 (set (match_dup 3)
34b650b3 865 (ltu:SI (subreg:SI (match_dup 0) 0)
8ef30996
MM
866 (match_dup 2)))
867
ddef6bc7
JJ
868 (set (subreg:SI (match_dup 0) 4)
869 (plus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
870 (match_dup 3)))]
871 "")
872
873(define_split
874 [(set (match_operand:DI 0 "register_operand" "")
875 (plus:DI (match_operand:DI 1 "register_operand" "")
876 (match_operand:DI 2 "small_int" "")))
877 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3
GK
878 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
879 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
880 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
881 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
882 && INTVAL (operands[2]) > 0"
883
ddef6bc7
JJ
884 [(set (subreg:SI (match_dup 0) 4)
885 (plus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
886 (match_dup 2)))
887
888 (set (match_dup 3)
ddef6bc7 889 (ltu:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
890 (match_dup 2)))
891
892 (set (subreg:SI (match_dup 0) 0)
893 (plus:SI (subreg:SI (match_dup 1) 0)
894 (match_dup 3)))]
895 "")
bb621ad7
JW
896
897(define_insn "adddi3_internal_3"
898 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
899 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
900 (match_operand:DI 2 "se_arith_operand" "dI")))]
2bcb2ab3
GK
901 "TARGET_64BIT
902 && !TARGET_MIPS16
903 && (TARGET_GAS
904 || GET_CODE (operands[2]) != CONST_INT
905 || INTVAL (operands[2]) != -32768)"
bb621ad7
JW
906 "*
907{
908 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
909 ? \"dsubu\\t%0,%z1,%n2\"
910 : \"daddu\\t%0,%z1,%2\";
911}"
912 [(set_attr "type" "darith")
0ff83799 913 (set_attr "mode" "DI")])
bb621ad7 914
2bcb2ab3
GK
915;; For the mips16, we need to recognize stack pointer additions
916;; explicitly, since we don't have a constraint for $sp. These insns
917;; will be generated by the save_restore_insns functions.
918
919(define_insn ""
920 [(set (reg:DI 29)
921 (plus:DI (reg:DI 29)
922 (match_operand:DI 0 "small_int" "I")))]
923 "TARGET_MIPS16 && TARGET_64BIT"
924 "daddu\\t%$,%$,%0"
925 [(set_attr "type" "arith")
926 (set_attr "mode" "DI")
927 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
0ff83799
MM
928 (const_int 4)
929 (const_int 8)))])
2bcb2ab3
GK
930
931(define_insn ""
932 [(set (match_operand:DI 0 "register_operand" "=d")
933 (plus:DI (reg:DI 29)
934 (match_operand:DI 1 "small_int" "I")))]
935 "TARGET_MIPS16 && TARGET_64BIT"
936 "daddu\\t%0,%$,%1"
937 [(set_attr "type" "arith")
938 (set_attr "mode" "DI")
939 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
0ff83799
MM
940 (const_int 4)
941 (const_int 8)))])
2bcb2ab3
GK
942
943(define_insn ""
944 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
945 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
946 (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
947 "TARGET_MIPS16 && TARGET_64BIT
948 && (GET_CODE (operands[1]) != REG
949 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
950 || M16_REG_P (REGNO (operands[1]))
951 || REGNO (operands[1]) == ARG_POINTER_REGNUM
952 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
953 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
954 && (GET_CODE (operands[2]) != REG
955 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
956 || M16_REG_P (REGNO (operands[2]))
957 || REGNO (operands[2]) == ARG_POINTER_REGNUM
958 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
959 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
960 "*
961{
962 if (REGNO (operands[0]) == REGNO (operands[1]))
963 return \"daddu\\t%0,%2\";
964 return \"daddu\\t%0,%1,%2\";
965}"
966 [(set_attr "type" "arith")
967 (set_attr "mode" "DI")
968 (set_attr_alternative "length"
969 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
0ff83799
MM
970 (const_int 4)
971 (const_int 8))
2bcb2ab3 972 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
0ff83799
MM
973 (const_int 4)
974 (const_int 8))
975 (const_int 4)])])
2bcb2ab3
GK
976
977
978;; On the mips16, we can sometimes split an add of a constant which is
979;; a 4 byte instruction into two adds which are both 2 byte
980;; instructions. There are two cases: one where we are adding a
981;; constant plus a register to another register, and one where we are
982;; simply adding a constant to a register.
983
984(define_split
985 [(set (match_operand:DI 0 "register_operand" "")
986 (plus:DI (match_dup 0)
987 (match_operand:DI 1 "const_int_operand" "")))]
988 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
989 && GET_CODE (operands[0]) == REG
990 && M16_REG_P (REGNO (operands[0]))
991 && GET_CODE (operands[1]) == CONST_INT
992 && ((INTVAL (operands[1]) > 0xf
993 && INTVAL (operands[1]) <= 0xf + 0xf)
994 || (INTVAL (operands[1]) < - 0x10
995 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
996 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
997 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
998 "
999{
1000 HOST_WIDE_INT val = INTVAL (operands[1]);
1001
1002 if (val >= 0)
1003 {
1004 operands[1] = GEN_INT (0xf);
1005 operands[2] = GEN_INT (val - 0xf);
1006 }
1007 else
1008 {
1009 operands[1] = GEN_INT (- 0x10);
1010 operands[2] = GEN_INT (val + 0x10);
1011 }
1012}")
1013
1014(define_split
1015 [(set (match_operand:DI 0 "register_operand" "")
1016 (plus:DI (match_operand:DI 1 "register_operand" "")
1017 (match_operand:DI 2 "const_int_operand" "")))]
1018 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1019 && GET_CODE (operands[0]) == REG
1020 && M16_REG_P (REGNO (operands[0]))
1021 && GET_CODE (operands[1]) == REG
1022 && M16_REG_P (REGNO (operands[1]))
1023 && REGNO (operands[0]) != REGNO (operands[1])
1024 && GET_CODE (operands[2]) == CONST_INT
1025 && ((INTVAL (operands[2]) > 0x7
1026 && INTVAL (operands[2]) <= 0x7 + 0xf)
1027 || (INTVAL (operands[2]) < - 0x8
1028 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1029 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1030 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1031 "
1032{
1033 HOST_WIDE_INT val = INTVAL (operands[2]);
1034
1035 if (val >= 0)
1036 {
1037 operands[2] = GEN_INT (0x7);
1038 operands[3] = GEN_INT (val - 0x7);
1039 }
1040 else
1041 {
1042 operands[2] = GEN_INT (- 0x8);
1043 operands[3] = GEN_INT (val + 0x8);
1044 }
1045}")
bb621ad7
JW
1046
1047(define_insn "addsi3_internal_2"
1048 [(set (match_operand:DI 0 "register_operand" "=d")
1049 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1050 (match_operand:SI 2 "arith_operand" "dI"))))]
2bcb2ab3
GK
1051 "TARGET_64BIT
1052 && !TARGET_MIPS16
1053 && (TARGET_GAS
1054 || GET_CODE (operands[2]) != CONST_INT
1055 || INTVAL (operands[2]) != -32768)"
bb621ad7
JW
1056 "*
1057{
1058 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1059 ? \"subu\\t%0,%z1,%n2\"
1060 : \"addu\\t%0,%z1,%2\";
1061}"
1062 [(set_attr "type" "arith")
0ff83799 1063 (set_attr "mode" "SI")])
bb621ad7 1064
2bcb2ab3
GK
1065(define_insn ""
1066 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1067 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1068 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1069 "TARGET_MIPS16 && TARGET_64BIT"
1070 "*
1071{
1072 if (REGNO (operands[0]) == REGNO (operands[1]))
1073 return \"addu\\t%0,%2\";
1074 return \"addu\\t%0,%1,%2\";
1075}"
1076 [(set_attr "type" "arith")
1077 (set_attr "mode" "SI")
1078 (set_attr_alternative "length"
1079 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
0ff83799
MM
1080 (const_int 4)
1081 (const_int 8))
2bcb2ab3 1082 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
0ff83799
MM
1083 (const_int 4)
1084 (const_int 8))
1085 (const_int 4)])])
2bcb2ab3 1086
8ef30996
MM
1087\f
1088;;
1089;; ....................
1090;;
1091;; SUBTRACTION
1092;;
1093;; ....................
1094;;
1095
1096(define_insn "subdf3"
1097 [(set (match_operand:DF 0 "register_operand" "=f")
1098 (minus:DF (match_operand:DF 1 "register_operand" "f")
1099 (match_operand:DF 2 "register_operand" "f")))]
46299de9 1100 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
1101 "sub.d\\t%0,%1,%2"
1102 [(set_attr "type" "fadd")
0ff83799 1103 (set_attr "mode" "DF")])
8ef30996
MM
1104
1105(define_insn "subsf3"
1106 [(set (match_operand:SF 0 "register_operand" "=f")
1107 (minus:SF (match_operand:SF 1 "register_operand" "f")
1108 (match_operand:SF 2 "register_operand" "f")))]
1109 "TARGET_HARD_FLOAT"
1110 "sub.s\\t%0,%1,%2"
1111 [(set_attr "type" "fadd")
0ff83799 1112 (set_attr "mode" "SF")])
8ef30996 1113
71cd5224 1114(define_expand "subsi3"
8ef30996
MM
1115 [(set (match_operand:SI 0 "register_operand" "=d")
1116 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1117 (match_operand:SI 2 "arith_operand" "dI")))]
1118 ""
71cd5224
RS
1119 "
1120{
2bcb2ab3
GK
1121 if (GET_CODE (operands[2]) == CONST_INT
1122 && (INTVAL (operands[2]) == -32768
1123 || (TARGET_MIPS16
1124 && INTVAL (operands[2]) == -0x4000)))
71cd5224
RS
1125 operands[2] = force_reg (SImode, operands[2]);
1126}")
1127
1128(define_insn "subsi3_internal"
1129 [(set (match_operand:SI 0 "register_operand" "=d")
1130 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1131 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3
GK
1132 "!TARGET_MIPS16
1133 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
9b190d1c 1134 "subu\\t%0,%z1,%2"
8ef30996 1135 [(set_attr "type" "arith")
0ff83799 1136 (set_attr "mode" "SI")])
8ef30996 1137
2bcb2ab3
GK
1138;; For the mips16, we need to recognize stack pointer subtractions
1139;; explicitly, since we don't have a constraint for $sp. These insns
1140;; will be generated by the save_restore_insns functions.
1141
1142(define_insn ""
1143 [(set (reg:SI 29)
1144 (minus:SI (reg:SI 29)
1145 (match_operand:SI 0 "small_int" "I")))]
1146 "TARGET_MIPS16
1147 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1148 "addu\\t%$,%$,%n0"
1149 [(set_attr "type" "arith")
1150 (set_attr "mode" "SI")
1151 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
0ff83799
MM
1152 (const_int 4)
1153 (const_int 8)))])
2bcb2ab3
GK
1154
1155(define_insn ""
1156 [(set (match_operand:SI 0 "register_operand" "=d")
1157 (minus:SI (reg:SI 29)
1158 (match_operand:SI 1 "small_int" "I")))]
1159 "TARGET_MIPS16
1160 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1161 "addu\\t%0,%$,%n1"
1162 [(set_attr "type" "arith")
1163 (set_attr "mode" "SI")
1164 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
0ff83799
MM
1165 (const_int 4)
1166 (const_int 8)))])
2bcb2ab3
GK
1167
1168
1169(define_insn ""
1170 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1171 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1172 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1173 "TARGET_MIPS16
1174 && (GET_CODE (operands[2]) != CONST_INT
1175 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1176 "*
1177{
1178 if (REGNO (operands[0]) == REGNO (operands[1]))
1179 return \"subu\\t%0,%2\";
1180 return \"subu\\t%0,%1,%2\";
1181}"
1182 [(set_attr "type" "arith")
1183 (set_attr "mode" "SI")
1184 (set_attr_alternative "length"
1185 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
0ff83799
MM
1186 (const_int 4)
1187 (const_int 8))
2bcb2ab3 1188 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
0ff83799
MM
1189 (const_int 4)
1190 (const_int 8))
1191 (const_int 4)])])
2bcb2ab3
GK
1192
1193;; On the mips16, we can sometimes split an subtract of a constant
1194;; which is a 4 byte instruction into two adds which are both 2 byte
1195;; instructions. There are two cases: one where we are setting a
1196;; register to a register minus a constant, and one where we are
1197;; simply subtracting a constant from a register.
1198
1199(define_split
1200 [(set (match_operand:SI 0 "register_operand" "")
1201 (minus:SI (match_dup 0)
1202 (match_operand:SI 1 "const_int_operand" "")))]
1203 "TARGET_MIPS16 && reload_completed
1204 && GET_CODE (operands[0]) == REG
1205 && M16_REG_P (REGNO (operands[0]))
1206 && GET_CODE (operands[1]) == CONST_INT
1207 && ((INTVAL (operands[1]) > 0x80
1208 && INTVAL (operands[1]) <= 0x80 + 0x80)
1209 || (INTVAL (operands[1]) < - 0x7f
1210 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1211 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1212 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1213 "
1214{
1215 HOST_WIDE_INT val = INTVAL (operands[1]);
1216
1217 if (val >= 0)
1218 {
1219 operands[1] = GEN_INT (0x80);
1220 operands[2] = GEN_INT (val - 0x80);
1221 }
1222 else
1223 {
1224 operands[1] = GEN_INT (- 0x7f);
1225 operands[2] = GEN_INT (val + 0x7f);
1226 }
1227}")
1228
1229(define_split
1230 [(set (match_operand:SI 0 "register_operand" "")
1231 (minus:SI (match_operand:SI 1 "register_operand" "")
1232 (match_operand:SI 2 "const_int_operand" "")))]
1233 "TARGET_MIPS16 && reload_completed
1234 && GET_CODE (operands[0]) == REG
1235 && M16_REG_P (REGNO (operands[0]))
1236 && GET_CODE (operands[1]) == REG
1237 && M16_REG_P (REGNO (operands[1]))
1238 && REGNO (operands[0]) != REGNO (operands[1])
1239 && GET_CODE (operands[2]) == CONST_INT
1240 && ((INTVAL (operands[2]) > 0x8
1241 && INTVAL (operands[2]) <= 0x8 + 0x80)
1242 || (INTVAL (operands[2]) < - 0x7
1243 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1244 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1245 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1246 "
1247{
1248 HOST_WIDE_INT val = INTVAL (operands[2]);
1249
1250 if (val >= 0)
1251 {
1252 operands[2] = GEN_INT (0x8);
1253 operands[3] = GEN_INT (val - 0x8);
1254 }
1255 else
1256 {
1257 operands[2] = GEN_INT (- 0x7);
1258 operands[3] = GEN_INT (val + 0x7);
1259 }
1260}")
1261
8ef30996
MM
1262(define_expand "subdi3"
1263 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
1264 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1265 (match_operand:DI 2 "se_register_operand" "d")))
8ef30996 1266 (clobber (match_dup 3))])]
2bcb2ab3 1267 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
1268 "
1269{
1270 if (TARGET_64BIT)
1271 {
1272 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1273 operands[2]));
1274 DONE;
1275 }
1276
1277 operands[3] = gen_reg_rtx (SImode);
1278}")
8ef30996
MM
1279
1280(define_insn "subdi3_internal"
1281 [(set (match_operand:DI 0 "register_operand" "=d")
1282 (minus:DI (match_operand:DI 1 "register_operand" "d")
1283 (match_operand:DI 2 "register_operand" "d")))
1284 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 1285 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
1286 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1287 [(set_attr "type" "darith")
1288 (set_attr "mode" "DI")
0ff83799 1289 (set_attr "length" "16")])
8ef30996
MM
1290
1291(define_split
1292 [(set (match_operand:DI 0 "register_operand" "")
1293 (minus:DI (match_operand:DI 1 "register_operand" "")
1294 (match_operand:DI 2 "register_operand" "")))
1295 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1296 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1297 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1298 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1299 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1300 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1301
1302 [(set (match_dup 3)
34b650b3 1303 (ltu:SI (subreg:SI (match_dup 1) 0)
6d518002 1304 (subreg:SI (match_dup 2) 0)))
8ef30996
MM
1305
1306 (set (subreg:SI (match_dup 0) 0)
1307 (minus:SI (subreg:SI (match_dup 1) 0)
1308 (subreg:SI (match_dup 2) 0)))
1309
ddef6bc7
JJ
1310 (set (subreg:SI (match_dup 0) 4)
1311 (minus:SI (subreg:SI (match_dup 1) 4)
1312 (subreg:SI (match_dup 2) 4)))
8ef30996 1313
ddef6bc7
JJ
1314 (set (subreg:SI (match_dup 0) 4)
1315 (minus:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
1316 (match_dup 3)))]
1317 "")
1318
1319(define_split
1320 [(set (match_operand:DI 0 "register_operand" "")
1321 (minus:DI (match_operand:DI 1 "register_operand" "")
1322 (match_operand:DI 2 "register_operand" "")))
1323 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1324 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1325 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1326 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1327 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1328 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1329
1330 [(set (match_dup 3)
ddef6bc7
JJ
1331 (ltu:SI (subreg:SI (match_dup 1) 4)
1332 (subreg:SI (match_dup 2) 4)))
8ef30996 1333
ddef6bc7
JJ
1334 (set (subreg:SI (match_dup 0) 4)
1335 (minus:SI (subreg:SI (match_dup 1) 4)
1336 (subreg:SI (match_dup 2) 4)))
8ef30996
MM
1337
1338 (set (subreg:SI (match_dup 0) 0)
1339 (minus:SI (subreg:SI (match_dup 1) 0)
1340 (subreg:SI (match_dup 2) 0)))
1341
1342 (set (subreg:SI (match_dup 0) 0)
1343 (minus:SI (subreg:SI (match_dup 0) 0)
1344 (match_dup 3)))]
1345 "")
1346
1347(define_insn "subdi3_internal_2"
1348 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1349 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1350 (match_operand:DI 2 "small_int" "P,J,N")))
1351 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
2bcb2ab3
GK
1352 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1353 && INTVAL (operands[2]) != -32768"
8ef30996
MM
1354 "@
1355 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1356 move\\t%L0,%L1\;move\\t%M0,%M1
1357 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
92b4cee1
MM
1358 [(set_attr "type" "darith")
1359 (set_attr "mode" "DI")
0ff83799 1360 (set_attr "length" "12,8,16")])
8ef30996
MM
1361
1362(define_split
1363 [(set (match_operand:DI 0 "register_operand" "")
1364 (minus:DI (match_operand:DI 1 "register_operand" "")
1365 (match_operand:DI 2 "small_int" "")))
1366 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1367 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1368 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1369 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1370 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1371 && INTVAL (operands[2]) > 0"
1372
1373 [(set (match_dup 3)
34b650b3 1374 (ltu:SI (subreg:SI (match_dup 1) 0)
8ef30996
MM
1375 (match_dup 2)))
1376
1377 (set (subreg:SI (match_dup 0) 0)
1378 (minus:SI (subreg:SI (match_dup 1) 0)
1379 (match_dup 2)))
1380
ddef6bc7
JJ
1381 (set (subreg:SI (match_dup 0) 4)
1382 (minus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1383 (match_dup 3)))]
1384 "")
1385
1386(define_split
1387 [(set (match_operand:DI 0 "register_operand" "")
1388 (minus:DI (match_operand:DI 1 "register_operand" "")
1389 (match_operand:DI 2 "small_int" "")))
1390 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
1391 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1392 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
1393 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1394 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1395 && INTVAL (operands[2]) > 0"
1396
1397 [(set (match_dup 3)
ddef6bc7 1398 (ltu:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1399 (match_dup 2)))
1400
ddef6bc7
JJ
1401 (set (subreg:SI (match_dup 0) 4)
1402 (minus:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
1403 (match_dup 2)))
1404
1405 (set (subreg:SI (match_dup 0) 0)
1406 (minus:SI (subreg:SI (match_dup 1) 0)
1407 (match_dup 3)))]
1408 "")
1409
bb621ad7
JW
1410(define_insn "subdi3_internal_3"
1411 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
1412 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1413 (match_operand:DI 2 "se_arith_operand" "dI")))]
2bcb2ab3
GK
1414 "TARGET_64BIT && !TARGET_MIPS16
1415 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
bb621ad7
JW
1416 "*
1417{
1418 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1419 ? \"daddu\\t%0,%z1,%n2\"
1420 : \"dsubu\\t%0,%z1,%2\";
1421}"
1422 [(set_attr "type" "darith")
0ff83799 1423 (set_attr "mode" "DI")])
bb621ad7 1424
2bcb2ab3
GK
1425;; For the mips16, we need to recognize stack pointer subtractions
1426;; explicitly, since we don't have a constraint for $sp. These insns
1427;; will be generated by the save_restore_insns functions.
1428
1429(define_insn ""
1430 [(set (reg:DI 29)
1431 (minus:DI (reg:DI 29)
1432 (match_operand:DI 0 "small_int" "I")))]
1433 "TARGET_MIPS16
1434 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1435 "daddu\\t%$,%$,%n0"
1436 [(set_attr "type" "arith")
1437 (set_attr "mode" "DI")
1438 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
0ff83799
MM
1439 (const_int 4)
1440 (const_int 8)))])
2bcb2ab3
GK
1441
1442(define_insn ""
1443 [(set (match_operand:DI 0 "register_operand" "=d")
1444 (minus:DI (reg:DI 29)
1445 (match_operand:DI 1 "small_int" "I")))]
1446 "TARGET_MIPS16
1447 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1448 "daddu\\t%0,%$,%n1"
1449 [(set_attr "type" "arith")
1450 (set_attr "mode" "DI")
1451 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
0ff83799
MM
1452 (const_int 4)
1453 (const_int 8)))])
2bcb2ab3
GK
1454
1455(define_insn ""
1456 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1457 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1458 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1459 "TARGET_MIPS16
1460 && (GET_CODE (operands[2]) != CONST_INT
1461 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1462 "*
1463{
1464 if (REGNO (operands[0]) == REGNO (operands[1]))
1465 return \"dsubu\\t%0,%2\";
1466 return \"dsubu\\t%0,%1,%2\";
1467}"
1468 [(set_attr "type" "arith")
1469 (set_attr "mode" "DI")
1470 (set_attr_alternative "length"
1471 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
0ff83799
MM
1472 (const_int 4)
1473 (const_int 8))
2bcb2ab3 1474 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
0ff83799
MM
1475 (const_int 4)
1476 (const_int 8))
1477 (const_int 4)])])
2bcb2ab3
GK
1478
1479;; On the mips16, we can sometimes split an add of a constant which is
1480;; a 4 byte instruction into two adds which are both 2 byte
1481;; instructions. There are two cases: one where we are adding a
1482;; constant plus a register to another register, and one where we are
1483;; simply adding a constant to a register.
1484
1485(define_split
1486 [(set (match_operand:DI 0 "register_operand" "")
1487 (minus:DI (match_dup 0)
1488 (match_operand:DI 1 "const_int_operand" "")))]
1489 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1490 && GET_CODE (operands[0]) == REG
1491 && M16_REG_P (REGNO (operands[0]))
1492 && GET_CODE (operands[1]) == CONST_INT
1493 && ((INTVAL (operands[1]) > 0x10
1494 && INTVAL (operands[1]) <= 0x10 + 0x10)
1495 || (INTVAL (operands[1]) < - 0xf
1496 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1497 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1498 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1499 "
1500{
1501 HOST_WIDE_INT val = INTVAL (operands[1]);
1502
1503 if (val >= 0)
1504 {
1505 operands[1] = GEN_INT (0xf);
1506 operands[2] = GEN_INT (val - 0xf);
1507 }
1508 else
1509 {
1510 operands[1] = GEN_INT (- 0x10);
1511 operands[2] = GEN_INT (val + 0x10);
1512 }
1513}")
1514
1515(define_split
1516 [(set (match_operand:DI 0 "register_operand" "")
1517 (minus:DI (match_operand:DI 1 "register_operand" "")
1518 (match_operand:DI 2 "const_int_operand" "")))]
1519 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1520 && GET_CODE (operands[0]) == REG
1521 && M16_REG_P (REGNO (operands[0]))
1522 && GET_CODE (operands[1]) == REG
1523 && M16_REG_P (REGNO (operands[1]))
1524 && REGNO (operands[0]) != REGNO (operands[1])
1525 && GET_CODE (operands[2]) == CONST_INT
1526 && ((INTVAL (operands[2]) > 0x8
1527 && INTVAL (operands[2]) <= 0x8 + 0x10)
1528 || (INTVAL (operands[2]) < - 0x7
1529 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1530 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1531 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1532 "
1533{
1534 HOST_WIDE_INT val = INTVAL (operands[2]);
1535
1536 if (val >= 0)
1537 {
1538 operands[2] = GEN_INT (0x8);
1539 operands[3] = GEN_INT (val - 0x8);
1540 }
1541 else
1542 {
1543 operands[2] = GEN_INT (- 0x7);
1544 operands[3] = GEN_INT (val + 0x7);
1545 }
1546}")
bb621ad7
JW
1547
1548(define_insn "subsi3_internal_2"
1549 [(set (match_operand:DI 0 "register_operand" "=d")
1550 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1551 (match_operand:SI 2 "arith_operand" "dI"))))]
2bcb2ab3
GK
1552 "TARGET_64BIT && !TARGET_MIPS16
1553 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
bb621ad7
JW
1554 "*
1555{
1556 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1557 ? \"addu\\t%0,%z1,%n2\"
1558 : \"subu\\t%0,%z1,%2\";
1559}"
1560 [(set_attr "type" "arith")
0ff83799 1561 (set_attr "mode" "DI")])
bb621ad7 1562
2bcb2ab3
GK
1563(define_insn ""
1564 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1565 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1566 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1567 "TARGET_64BIT && TARGET_MIPS16
1568 && (GET_CODE (operands[2]) != CONST_INT
1569 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1570 "*
1571{
1572 if (REGNO (operands[0]) == REGNO (operands[1]))
1573 return \"subu\\t%0,%2\";
1574 return \"subu\\t%0,%1,%2\";
1575}"
1576 [(set_attr "type" "arith")
1577 (set_attr "mode" "SI")
1578 (set_attr_alternative "length"
1579 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
0ff83799
MM
1580 (const_int 4)
1581 (const_int 8))
2bcb2ab3 1582 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
0ff83799
MM
1583 (const_int 4)
1584 (const_int 8))
1585 (const_int 4)])])
2bcb2ab3
GK
1586
1587
8ef30996
MM
1588\f
1589;;
1590;; ....................
1591;;
1592;; MULTIPLICATION
1593;;
1594;; ....................
1595;;
1596
aa4e54c4
JW
1597;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1598;; operands may corrupt immediately following multiplies. This is a
1599;; simple fix to insert NOPs.
8fbaea49
JW
1600
1601(define_expand "muldf3"
8ef30996
MM
1602 [(set (match_operand:DF 0 "register_operand" "=f")
1603 (mult:DF (match_operand:DF 1 "register_operand" "f")
1604 (match_operand:DF 2 "register_operand" "f")))]
46299de9 1605 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8fbaea49
JW
1606 "
1607{
1608 if (mips_cpu != PROCESSOR_R4300)
1609 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1610 else
1611 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1612 DONE;
1613}")
1614
1615(define_insn "muldf3_internal"
1616 [(set (match_operand:DF 0 "register_operand" "=f")
1617 (mult:DF (match_operand:DF 1 "register_operand" "f")
1618 (match_operand:DF 2 "register_operand" "f")))]
1619 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
8ef30996
MM
1620 "mul.d\\t%0,%1,%2"
1621 [(set_attr "type" "fmul")
0ff83799 1622 (set_attr "mode" "DF")])
8ef30996 1623
8fbaea49
JW
1624(define_insn "muldf3_r4300"
1625 [(set (match_operand:DF 0 "register_operand" "=f")
1626 (mult:DF (match_operand:DF 1 "register_operand" "f")
1627 (match_operand:DF 2 "register_operand" "f")))]
1628 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
1629 "*
1630{
1631 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1632 if (TARGET_4300_MUL_FIX)
1633 output_asm_insn (\"nop\", operands);
1634 return \"\";
1635}"
1636 [(set_attr "type" "fmul")
1637 (set_attr "mode" "DF")
0ff83799 1638 (set_attr "length" "8")]) ;; mul.d + nop
8fbaea49
JW
1639
1640(define_expand "mulsf3"
8ef30996
MM
1641 [(set (match_operand:SF 0 "register_operand" "=f")
1642 (mult:SF (match_operand:SF 1 "register_operand" "f")
1643 (match_operand:SF 2 "register_operand" "f")))]
1644 "TARGET_HARD_FLOAT"
8fbaea49
JW
1645 "
1646{
1647 if (mips_cpu != PROCESSOR_R4300)
1648 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1649 else
1650 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1651 DONE;
1652}")
1653
1654(define_insn "mulsf3_internal"
1655 [(set (match_operand:SF 0 "register_operand" "=f")
1656 (mult:SF (match_operand:SF 1 "register_operand" "f")
1657 (match_operand:SF 2 "register_operand" "f")))]
1658 "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
8ef30996
MM
1659 "mul.s\\t%0,%1,%2"
1660 [(set_attr "type" "fmul")
0ff83799 1661 (set_attr "mode" "SF")])
8ef30996 1662
8fbaea49
JW
1663(define_insn "mulsf3_r4300"
1664 [(set (match_operand:SF 0 "register_operand" "=f")
1665 (mult:SF (match_operand:SF 1 "register_operand" "f")
1666 (match_operand:SF 2 "register_operand" "f")))]
1667 "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1668 "*
1669{
1670 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1671 if (TARGET_4300_MUL_FIX)
1672 output_asm_insn (\"nop\", operands);
1673 return \"\";
1674}"
1675 [(set_attr "type" "fmul")
1676 (set_attr "mode" "SF")
0ff83799 1677 (set_attr "length" "8")]) ;; mul.s + nop
8fbaea49 1678
cb923660 1679
46299de9
ILT
1680;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1681;; a multiply is in progress, it may give an incorrect result. Avoid
1682;; this by keeping the mflo with the mult on the R4000.
1683
1684(define_expand "mulsi3"
1685 [(set (match_operand:SI 0 "register_operand" "=l")
8ef30996
MM
1686 (mult:SI (match_operand:SI 1 "register_operand" "d")
1687 (match_operand:SI 2 "register_operand" "d")))
225b8835
ILT
1688 (clobber (match_scratch:SI 3 "=h"))
1689 (clobber (match_scratch:SI 4 "=a"))]
8ef30996 1690 ""
46299de9
ILT
1691 "
1692{
e4f5c5d6 1693 if (HAVE_mulsi3_mult3)
e9a25f70 1694 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
2bcb2ab3 1695 else if (mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16)
46299de9
ILT
1696 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1697 else
1698 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1699 DONE;
1700}")
1701
e9a25f70 1702(define_insn "mulsi3_mult3"
e4f5c5d6 1703 [(set (match_operand:SI 0 "register_operand" "=d,l")
cb923660
KR
1704 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1705 (match_operand:SI 2 "register_operand" "d,d")))
1706 (clobber (match_scratch:SI 3 "=h,h"))
1707 (clobber (match_scratch:SI 4 "=l,X"))
1708 (clobber (match_scratch:SI 5 "=a,a"))]
e4f5c5d6
KR
1709 "GENERATE_MULT3
1710 || TARGET_MAD"
cb923660
KR
1711 "*
1712{
1713 if (which_alternative == 1)
1714 return \"mult\\t%1,%2\";
1715 if (TARGET_MAD)
1716 return \"mul\\t%0,%1,%2\";
1717 return \"mult\\t%0,%1,%2\";
1718}"
e9a25f70 1719 [(set_attr "type" "imul")
0ff83799 1720 (set_attr "mode" "SI")])
e9a25f70 1721
46299de9
ILT
1722(define_insn "mulsi3_internal"
1723 [(set (match_operand:SI 0 "register_operand" "=l")
1724 (mult:SI (match_operand:SI 1 "register_operand" "d")
1725 (match_operand:SI 2 "register_operand" "d")))
225b8835
ILT
1726 (clobber (match_scratch:SI 3 "=h"))
1727 (clobber (match_scratch:SI 4 "=a"))]
2bcb2ab3 1728 "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16"
46299de9
ILT
1729 "mult\\t%1,%2"
1730 [(set_attr "type" "imul")
0ff83799 1731 (set_attr "mode" "SI")])
46299de9
ILT
1732
1733(define_insn "mulsi3_r4000"
1734 [(set (match_operand:SI 0 "register_operand" "=d")
1735 (mult:SI (match_operand:SI 1 "register_operand" "d")
1736 (match_operand:SI 2 "register_operand" "d")))
1737 (clobber (match_scratch:SI 3 "=h"))
225b8835
ILT
1738 (clobber (match_scratch:SI 4 "=l"))
1739 (clobber (match_scratch:SI 5 "=a"))]
2bcb2ab3 1740 "mips_cpu == PROCESSOR_R4000 && !TARGET_MIPS16"
8ef30996
MM
1741 "*
1742{
1743 rtx xoperands[10];
1744
1745 xoperands[0] = operands[0];
c5c76735 1746 xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
8ef30996
MM
1747
1748 output_asm_insn (\"mult\\t%1,%2\", operands);
bb621ad7 1749 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
8ef30996
MM
1750 return \"\";
1751}"
1752 [(set_attr "type" "imul")
1753 (set_attr "mode" "SI")
0ff83799 1754 (set_attr "length" "12")]) ;; mult + mflo + delay
8ef30996 1755
e4f5c5d6
KR
1756;; Multiply-accumulate patterns
1757
1758;; For processors that can copy the output to a general register:
1759;;
cb923660
KR
1760;; The all-d alternative is needed because the combiner will find this
1761;; pattern and then register alloc/reload will move registers around to
1762;; make them fit, and we don't want to trigger unnecessary loads to LO.
e4f5c5d6
KR
1763;;
1764;; The last alternative should be made slightly less desirable, but adding
1765;; "?" to the constraint is too strong, and causes values to be loaded into
1766;; LO even when that's more costly. For now, using "*d" mostly does the
1767;; trick.
cb923660 1768(define_insn "*mul_acc_si"
e4f5c5d6 1769 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
cb923660
KR
1770 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1771 (match_operand:SI 2 "register_operand" "d,d,d"))
e4f5c5d6 1772 (match_operand:SI 3 "register_operand" "0,l,*d")))
cb923660
KR
1773 (clobber (match_scratch:SI 4 "=h,h,h"))
1774 (clobber (match_scratch:SI 5 "=X,3,l"))
1775 (clobber (match_scratch:SI 6 "=a,a,a"))
1776 (clobber (match_scratch:SI 7 "=X,X,d"))]
e4f5c5d6
KR
1777 "TARGET_MIPS3900
1778 && !TARGET_MIPS16"
cb923660
KR
1779 "*
1780{
e2fe6aba 1781 static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
cb923660
KR
1782 if (which_alternative == 2)
1783 return \"#\";
1784 return madd[which_alternative];
1785}"
1786 [(set_attr "type" "imul,imul,multi")
053665d7 1787 (set_attr "mode" "SI")
0ff83799 1788 (set_attr "length" "4,4,8")])
cb923660 1789
e4f5c5d6 1790;; Split the above insn if we failed to get LO allocated.
cb923660
KR
1791(define_split
1792 [(set (match_operand:SI 0 "register_operand" "")
1793 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1794 (match_operand:SI 2 "register_operand" ""))
1795 (match_operand:SI 3 "register_operand" "")))
1796 (clobber (match_scratch:SI 4 ""))
1797 (clobber (match_scratch:SI 5 ""))
1798 (clobber (match_scratch:SI 6 ""))
1799 (clobber (match_scratch:SI 7 ""))]
1800 "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[3]))"
1801 [(parallel [(set (match_dup 7)
1802 (mult:SI (match_dup 1) (match_dup 2)))
1803 (clobber (match_dup 4))
1804 (clobber (match_dup 5))
1805 (clobber (match_dup 6))])
1806 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1807 "")
1808
1809(define_split
1810 [(set (match_operand:SI 0 "register_operand" "")
1811 (minus:SI (match_operand:SI 1 "register_operand" "")
1812 (mult:SI (match_operand:SI 2 "register_operand" "")
1813 (match_operand:SI 3 "register_operand" ""))))
1814 (clobber (match_scratch:SI 4 ""))
1815 (clobber (match_scratch:SI 5 ""))
1816 (clobber (match_scratch:SI 6 ""))
1817 (clobber (match_scratch:SI 7 ""))]
1818 "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[1]))"
1819 [(parallel [(set (match_dup 7)
1820 (mult:SI (match_dup 2) (match_dup 3)))
1821 (clobber (match_dup 4))
1822 (clobber (match_dup 5))
1823 (clobber (match_dup 6))])
1824 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1825 "")
053665d7 1826
46299de9
ILT
1827(define_expand "muldi3"
1828 [(set (match_operand:DI 0 "register_operand" "=l")
1908a152 1829 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
46299de9 1830 (match_operand:DI 2 "register_operand" "d")))
225b8835
ILT
1831 (clobber (match_scratch:DI 3 "=h"))
1832 (clobber (match_scratch:DI 4 "=a"))]
46299de9 1833 "TARGET_64BIT"
cb923660 1834
46299de9
ILT
1835 "
1836{
2bcb2ab3 1837 if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)
868e82ab 1838 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
46299de9 1839 else
868e82ab 1840 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
46299de9
ILT
1841 DONE;
1842}")
8ef30996 1843
1908a152
ILT
1844;; Don't accept both operands using se_register_operand, because if
1845;; both operands are sign extended we would prefer to use mult in the
1846;; mulsidi3 pattern. Commutativity should permit either operand to be
1847;; sign extended.
1848
46299de9
ILT
1849(define_insn "muldi3_internal"
1850 [(set (match_operand:DI 0 "register_operand" "=l")
1908a152 1851 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
46299de9 1852 (match_operand:DI 2 "register_operand" "d")))
225b8835
ILT
1853 (clobber (match_scratch:DI 3 "=h"))
1854 (clobber (match_scratch:DI 4 "=a"))]
2bcb2ab3 1855 "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16"
e7faa2f6 1856 "dmult\\t%1,%2"
8ef30996 1857 [(set_attr "type" "imul")
0ff83799 1858 (set_attr "mode" "DI")])
8ef30996 1859
868e82ab 1860(define_insn "muldi3_internal2"
bb621ad7 1861 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 1862 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 1863 (match_operand:DI 2 "register_operand" "d")))
46299de9 1864 (clobber (match_scratch:DI 3 "=h"))
225b8835
ILT
1865 (clobber (match_scratch:DI 4 "=l"))
1866 (clobber (match_scratch:DI 5 "=a"))]
319f217e 1867 "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)"
bb621ad7
JW
1868 "*
1869{
868e82ab
GK
1870 if (GENERATE_MULT3)
1871 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1872 else
1873 {
c5c76735 1874 rtx xoperands[10];
bb621ad7 1875
c5c76735
JL
1876 xoperands[0] = operands[0];
1877 xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
bb621ad7 1878
c5c76735
JL
1879 output_asm_insn (\"dmult\\t%1,%2\", operands);
1880 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
868e82ab 1881 }
bb621ad7
JW
1882 return \"\";
1883}"
1884 [(set_attr "type" "imul")
1885 (set_attr "mode" "DI")
868e82ab
GK
1886 (set (attr "length")
1887 (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
0ff83799
MM
1888 (const_int 4)
1889 (const_int 12)))]) ;; mult + mflo + delay
bb621ad7 1890
bb621ad7
JW
1891;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1892
225b8835 1893(define_expand "mulsidi3"
46299de9 1894 [(set (match_operand:DI 0 "register_operand" "=x")
8ef30996 1895 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
46299de9 1896 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
225b8835
ILT
1897 ""
1898 "
1899{
cb923660 1900 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
225b8835 1901 if (TARGET_64BIT)
cb923660
KR
1902 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1903 dummy, dummy));
225b8835 1904 else
cb923660
KR
1905 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1906 dummy, dummy));
225b8835
ILT
1907 DONE;
1908}")
1909
225b8835 1910(define_expand "umulsidi3"
46299de9 1911 [(set (match_operand:DI 0 "register_operand" "=x")
8ef30996 1912 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
46299de9 1913 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
225b8835
ILT
1914 ""
1915 "
1916{
cb923660 1917 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
225b8835 1918 if (TARGET_64BIT)
cb923660
KR
1919 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1920 dummy, dummy));
225b8835 1921 else
cb923660
KR
1922 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1923 dummy, dummy));
225b8835
ILT
1924 DONE;
1925}")
1926
cb923660 1927(define_insn "mulsidi3_internal"
225b8835 1928 [(set (match_operand:DI 0 "register_operand" "=x")
cb923660
KR
1929 (mult:DI (match_operator:DI 3 "extend_operator"
1930 [(match_operand:SI 1 "register_operand" "d")])
1931 (match_operator:DI 4 "extend_operator"
1932 [(match_operand:SI 2 "register_operand" "d")])))
1933 (clobber (match_scratch:SI 5 "=a"))]
1934 "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1935 "*
1936{
1937 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1938 return \"mult\\t%1,%2\";
1939 return \"multu\\t%1,%2\";
1940}"
8ef30996 1941 [(set_attr "type" "imul")
0ff83799 1942 (set_attr "mode" "SI")])
8ef30996 1943
cb923660 1944(define_insn "mulsidi3_64bit"
225b8835 1945 [(set (match_operand:DI 0 "register_operand" "=a")
cb923660
KR
1946 (mult:DI (match_operator:DI 3 "extend_operator"
1947 [(match_operand:SI 1 "register_operand" "d")])
1948 (match_operator:DI 4 "extend_operator"
1949 [(match_operand:SI 2 "register_operand" "d")])))
1950 (clobber (match_scratch:DI 5 "=l"))
1951 (clobber (match_scratch:DI 6 "=h"))]
1952 "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1953 "*
1954{
1955 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1956 return \"mult\\t%1,%2\";
1957 return \"multu\\t%1,%2\";
1958}"
225b8835 1959 [(set_attr "type" "imul")
0ff83799 1960 (set_attr "mode" "SI")])
225b8835 1961
cb923660
KR
1962;; _highpart patterns
1963(define_expand "smulsi3_highpart"
1964 [(set (match_operand:SI 0 "register_operand" "=h")
1965 (truncate:SI
1966 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1967 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1968 (const_int 32))))]
1969 ""
1970 "
1971{
1972 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1973 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
e4f5c5d6 1974#ifndef NO_MD_PROTOTYPES
f6da8bc3 1975 rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
e4f5c5d6
KR
1976#else
1977 rtx (*genfn) ();
1978#endif
1979 genfn = gen_xmulsi3_highpart_internal;
cb923660
KR
1980 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1981 dummy, dummy2));
1982 DONE;
1983}")
1984
1985(define_expand "umulsi3_highpart"
46299de9 1986 [(set (match_operand:SI 0 "register_operand" "=h")
903df3fe
JW
1987 (truncate:SI
1988 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1989 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
cb923660 1990 (const_int 32))))]
903df3fe 1991 ""
cb923660
KR
1992 "
1993{
1994 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1995 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
e4f5c5d6 1996#ifndef NO_MD_PROTOTYPES
f6da8bc3 1997 rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
e4f5c5d6
KR
1998#else
1999 rtx (*genfn) ();
2000#endif
2001 genfn = gen_xmulsi3_highpart_internal;
cb923660
KR
2002 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
2003 dummy, dummy2));
2004 DONE;
2005}")
2006
2007(define_insn "xmulsi3_highpart_internal"
2008 [(set (match_operand:SI 0 "register_operand" "=h")
2009 (truncate:SI
2010 (match_operator:DI 5 "highpart_shift_operator"
2011 [(mult:DI (match_operator:DI 3 "extend_operator"
2012 [(match_operand:SI 1 "register_operand" "d")])
2013 (match_operator:DI 4 "extend_operator"
2014 [(match_operand:SI 2 "register_operand" "d")]))
2015 (const_int 32)])))
2016 (clobber (match_scratch:SI 6 "=l"))
2017 (clobber (match_scratch:SI 7 "=a"))]
2018 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
2019 "*
2020{
2021 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2022 return \"mult\\t%1,%2\";
2023 else
2024 return \"multu\\t%1,%2\";
2025}"
903df3fe 2026 [(set_attr "type" "imul")
0ff83799 2027 (set_attr "mode" "SI")])
48199e32
JW
2028
2029(define_insn "smuldi3_highpart"
46299de9 2030 [(set (match_operand:DI 0 "register_operand" "=h")
48199e32 2031 (truncate:DI
1908a152
ILT
2032 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2033 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
48199e32 2034 (const_int 64))))
225b8835
ILT
2035 (clobber (match_scratch:DI 3 "=l"))
2036 (clobber (match_scratch:DI 4 "=a"))]
48199e32 2037 "TARGET_64BIT"
46299de9 2038 "dmult\\t%1,%2"
48199e32 2039 [(set_attr "type" "imul")
0ff83799 2040 (set_attr "mode" "DI")])
48199e32
JW
2041
2042(define_insn "umuldi3_highpart"
46299de9 2043 [(set (match_operand:DI 0 "register_operand" "=h")
48199e32 2044 (truncate:DI
1908a152
ILT
2045 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2046 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
48199e32 2047 (const_int 64))))
225b8835
ILT
2048 (clobber (match_scratch:DI 3 "=l"))
2049 (clobber (match_scratch:DI 4 "=a"))]
48199e32 2050 "TARGET_64BIT"
46299de9 2051 "dmultu\\t%1,%2"
48199e32 2052 [(set_attr "type" "imul")
0ff83799 2053 (set_attr "mode" "DI")])
48199e32 2054
46299de9
ILT
2055;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2056;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2057
2058(define_insn "madsi"
2059 [(set (match_operand:SI 0 "register_operand" "+l")
2060 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2061 (match_operand:SI 2 "register_operand" "d"))
2062 (match_dup 0)))
225b8835
ILT
2063 (clobber (match_scratch:SI 3 "=h"))
2064 (clobber (match_scratch:SI 4 "=a"))]
cb923660 2065 "TARGET_MAD"
225b8835
ILT
2066 "mad\\t%1,%2"
2067 [(set_attr "type" "imul")
0ff83799 2068 (set_attr "mode" "SI")])
225b8835 2069
cb923660 2070(define_insn "*mul_acc_di"
46299de9 2071 [(set (match_operand:DI 0 "register_operand" "+x")
cb923660
KR
2072 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2073 [(match_operand:SI 1 "register_operand" "d")])
e4f5c5d6 2074 (match_operator:DI 4 "extend_operator"
cb923660 2075 [(match_operand:SI 2 "register_operand" "d")]))
225b8835 2076 (match_dup 0)))
e4f5c5d6
KR
2077 (clobber (match_scratch:SI 5 "=a"))]
2078 "TARGET_MAD
2079 && ! TARGET_64BIT
2080 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
cb923660
KR
2081 "*
2082{
2083 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2084 return \"mad\\t%1,%2\";
2085 else
2086 return \"madu\\t%1,%2\";
2087}"
46299de9 2088 [(set_attr "type" "imul")
0ff83799 2089 (set_attr "mode" "SI")])
e19ff60f 2090
cb923660 2091(define_insn "*mul_acc_64bit_di"
225b8835 2092 [(set (match_operand:DI 0 "register_operand" "+a")
cb923660
KR
2093 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2094 [(match_operand:SI 1 "register_operand" "d")])
e4f5c5d6 2095 (match_operator:DI 4 "extend_operator"
cb923660 2096 [(match_operand:SI 2 "register_operand" "d")]))
225b8835 2097 (match_dup 0)))
e4f5c5d6
KR
2098 (clobber (match_scratch:SI 5 "=h"))
2099 (clobber (match_scratch:SI 6 "=l"))]
2100 "TARGET_MAD
2101 && TARGET_64BIT
2102 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
cb923660
KR
2103 "*
2104{
2105 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2106 return \"mad\\t%1,%2\";
2107 else
2108 return \"madu\\t%1,%2\";
2109}"
e9a25f70 2110 [(set_attr "type" "imul")
0ff83799 2111 (set_attr "mode" "SI")])
e9a25f70 2112
e19ff60f
JW
2113;; Floating point multiply accumulate instructions.
2114
2115(define_insn ""
2116 [(set (match_operand:DF 0 "register_operand" "=f")
2117 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2118 (match_operand:DF 2 "register_operand" "f"))
2119 (match_operand:DF 3 "register_operand" "f")))]
1d5d552e 2120 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f
JW
2121 "madd.d\\t%0,%3,%1,%2"
2122 [(set_attr "type" "fmadd")
0ff83799 2123 (set_attr "mode" "DF")])
e19ff60f
JW
2124
2125(define_insn ""
2126 [(set (match_operand:SF 0 "register_operand" "=f")
2127 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2128 (match_operand:SF 2 "register_operand" "f"))
2129 (match_operand:SF 3 "register_operand" "f")))]
1d5d552e 2130 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
e19ff60f
JW
2131 "madd.s\\t%0,%3,%1,%2"
2132 [(set_attr "type" "fmadd")
0ff83799 2133 (set_attr "mode" "SF")])
e19ff60f
JW
2134
2135(define_insn ""
2136 [(set (match_operand:DF 0 "register_operand" "=f")
2137 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2138 (match_operand:DF 2 "register_operand" "f"))
2139 (match_operand:DF 3 "register_operand" "f")))]
1d5d552e 2140 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f
JW
2141 "msub.d\\t%0,%3,%1,%2"
2142 [(set_attr "type" "fmadd")
0ff83799 2143 (set_attr "mode" "DF")])
e19ff60f
JW
2144
2145(define_insn ""
2146 [(set (match_operand:SF 0 "register_operand" "=f")
2147 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2148 (match_operand:SF 2 "register_operand" "f"))
2149 (match_operand:SF 3 "register_operand" "f")))]
2150
1d5d552e 2151 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
e19ff60f
JW
2152 "msub.s\\t%0,%3,%1,%2"
2153 [(set_attr "type" "fmadd")
0ff83799 2154 (set_attr "mode" "SF")])
e19ff60f
JW
2155
2156(define_insn ""
2157 [(set (match_operand:DF 0 "register_operand" "=f")
2158 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2159 (match_operand:DF 2 "register_operand" "f"))
2160 (match_operand:DF 3 "register_operand" "f"))))]
1d5d552e 2161 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f
JW
2162 "nmadd.d\\t%0,%3,%1,%2"
2163 [(set_attr "type" "fmadd")
0ff83799 2164 (set_attr "mode" "DF")])
e19ff60f
JW
2165
2166(define_insn ""
2167 [(set (match_operand:SF 0 "register_operand" "=f")
2168 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2169 (match_operand:SF 2 "register_operand" "f"))
2170 (match_operand:SF 3 "register_operand" "f"))))]
1d5d552e 2171 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
e19ff60f
JW
2172 "nmadd.s\\t%0,%3,%1,%2"
2173 [(set_attr "type" "fmadd")
0ff83799 2174 (set_attr "mode" "SF")])
e19ff60f
JW
2175
2176(define_insn ""
2177 [(set (match_operand:DF 0 "register_operand" "=f")
2178 (minus:DF (match_operand:DF 1 "register_operand" "f")
2179 (mult:DF (match_operand:DF 2 "register_operand" "f")
2180 (match_operand:DF 3 "register_operand" "f"))))]
1d5d552e 2181 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f
JW
2182 "nmsub.d\\t%0,%1,%2,%3"
2183 [(set_attr "type" "fmadd")
0ff83799 2184 (set_attr "mode" "DF")])
e19ff60f
JW
2185
2186(define_insn ""
2187 [(set (match_operand:SF 0 "register_operand" "=f")
2188 (minus:SF (match_operand:SF 1 "register_operand" "f")
2189 (mult:SF (match_operand:SF 2 "register_operand" "f")
2190 (match_operand:SF 3 "register_operand" "f"))))]
1d5d552e 2191 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
e19ff60f
JW
2192 "nmsub.s\\t%0,%1,%2,%3"
2193 [(set_attr "type" "fmadd")
0ff83799 2194 (set_attr "mode" "SF")])
8ef30996
MM
2195\f
2196;;
2197;; ....................
2198;;
2199;; DIVISION and REMAINDER
2200;;
2201;; ....................
2202;;
2203
2204(define_insn "divdf3"
2205 [(set (match_operand:DF 0 "register_operand" "=f")
2206 (div:DF (match_operand:DF 1 "register_operand" "f")
2207 (match_operand:DF 2 "register_operand" "f")))]
46299de9 2208 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
2209 "div.d\\t%0,%1,%2"
2210 [(set_attr "type" "fdiv")
0ff83799 2211 (set_attr "mode" "DF")])
8ef30996
MM
2212
2213(define_insn "divsf3"
2214 [(set (match_operand:SF 0 "register_operand" "=f")
2215 (div:SF (match_operand:SF 1 "register_operand" "f")
2216 (match_operand:SF 2 "register_operand" "f")))]
2217 "TARGET_HARD_FLOAT"
2218 "div.s\\t%0,%1,%2"
2219 [(set_attr "type" "fdiv")
0ff83799 2220 (set_attr "mode" "SF")])
8ef30996 2221
b8eb88d0
ILT
2222(define_insn ""
2223 [(set (match_operand:DF 0 "register_operand" "=f")
2224 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2225 (match_operand:DF 2 "register_operand" "f")))]
de6c5979 2226 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0
ILT
2227 "recip.d\\t%0,%2"
2228 [(set_attr "type" "fdiv")
0ff83799 2229 (set_attr "mode" "DF")])
b8eb88d0
ILT
2230
2231(define_insn ""
2232 [(set (match_operand:SF 0 "register_operand" "=f")
2233 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2234 (match_operand:SF 2 "register_operand" "f")))]
de6c5979 2235 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0
ILT
2236 "recip.s\\t%0,%2"
2237 [(set_attr "type" "fdiv")
0ff83799 2238 (set_attr "mode" "SF")])
b8eb88d0 2239
8ef30996
MM
2240;; If optimizing, prefer the divmod functions over separate div and
2241;; mod functions, since this will allow using one instruction for both
2242;; the quotient and remainder. At present, the divmod is not moved out
2243;; of loops if it is constant within the loop, so allow -mdebugc to
2244;; use the old method of doing things.
2245
2246;; 64 is the multiply/divide hi register
2247;; 65 is the multiply/divide lo register
2248
bb621ad7
JW
2249;; ??? We can't accept constants here, because the MIPS assembler will replace
2250;; a divide by power of 2 with a shift, and then the remainder is no longer
2251;; available.
2252
08c2951c 2253(define_expand "divmodsi4"
70252580
MM
2254 [(set (match_operand:SI 0 "register_operand" "=d")
2255 (div:SI (match_operand:SI 1 "register_operand" "d")
2256 (match_operand:SI 2 "register_operand" "d")))
2257 (set (match_operand:SI 3 "register_operand" "=d")
2258 (mod:SI (match_dup 1)
2259 (match_dup 2)))
46299de9 2260 (clobber (match_scratch:SI 4 "=l"))
225b8835
ILT
2261 (clobber (match_scratch:SI 5 "=h"))
2262 (clobber (match_scratch:SI 6 "=a"))]
34b650b3 2263 "optimize"
08c2951c 2264 "
8ef30996 2265{
08c2951c
SC
2266 emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2267 operands[3]));
2268 if (!TARGET_NO_CHECK_ZERO_DIV)
2269 {
2270 emit_insn (gen_div_trap (operands[2],
1feed51c 2271 GEN_INT (0),
08c2951c
SC
2272 GEN_INT (0x7)));
2273 }
2274 if (TARGET_CHECK_RANGE_DIV)
2275 {
2276 emit_insn (gen_div_trap (operands[2],
2277 copy_to_mode_reg (SImode, GEN_INT (-1)),
2278 GEN_INT (0x6)));
2279 emit_insn (gen_div_trap (operands[2],
3a6ee9f4 2280 copy_to_mode_reg (SImode, GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2281 GEN_INT (0x6)));
2282 }
2283
2284 DONE;
2285}")
8ef30996 2286
08c2951c
SC
2287(define_insn "divmodsi4_internal"
2288 [(set (match_operand:SI 0 "register_operand" "=l")
2289 (div:SI (match_operand:SI 1 "register_operand" "d")
2290 (match_operand:SI 2 "register_operand" "d")))
2291 (set (match_operand:SI 3 "register_operand" "=h")
2292 (mod:SI (match_dup 1)
2293 (match_dup 2)))
c77e04ae 2294 (clobber (match_scratch:SI 4 "=a"))]
08c2951c
SC
2295 "optimize"
2296 "div\\t$0,%1,%2"
8ef30996 2297 [(set_attr "type" "idiv")
0ff83799 2298 (set_attr "mode" "SI")])
bb621ad7 2299
08c2951c 2300(define_expand "divmoddi4"
bb621ad7 2301 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
2302 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2303 (match_operand:DI 2 "se_register_operand" "d")))
bb621ad7
JW
2304 (set (match_operand:DI 3 "register_operand" "=d")
2305 (mod:DI (match_dup 1)
2306 (match_dup 2)))
46299de9 2307 (clobber (match_scratch:DI 4 "=l"))
225b8835
ILT
2308 (clobber (match_scratch:DI 5 "=h"))
2309 (clobber (match_scratch:DI 6 "=a"))]
bb621ad7 2310 "TARGET_64BIT && optimize"
08c2951c 2311 "
bb621ad7 2312{
08c2951c
SC
2313 emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2314 operands[3]));
2315 if (!TARGET_NO_CHECK_ZERO_DIV)
2316 {
2317 emit_insn (gen_div_trap (operands[2],
1feed51c 2318 GEN_INT (0),
08c2951c
SC
2319 GEN_INT (0x7)));
2320 }
2321 if (TARGET_CHECK_RANGE_DIV)
2322 {
2323 emit_insn (gen_div_trap (operands[2],
2324 copy_to_mode_reg (DImode, GEN_INT (-1)),
2325 GEN_INT (0x6)));
2326 emit_insn (gen_div_trap (operands[2],
3a6ee9f4 2327 copy_to_mode_reg (DImode, GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2328 GEN_INT (0x6)));
2329 }
2330
2331 DONE;
2332}")
bb621ad7 2333
08c2951c
SC
2334(define_insn "divmoddi4_internal"
2335 [(set (match_operand:DI 0 "register_operand" "=l")
2336 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2337 (match_operand:DI 2 "se_register_operand" "d")))
2338 (set (match_operand:DI 3 "register_operand" "=h")
2339 (mod:DI (match_dup 1)
2340 (match_dup 2)))
c77e04ae 2341 (clobber (match_scratch:DI 4 "=a"))]
08c2951c
SC
2342 "TARGET_64BIT && optimize"
2343 "ddiv\\t$0,%1,%2"
bb621ad7 2344 [(set_attr "type" "idiv")
0ff83799 2345 (set_attr "mode" "SI")])
8ef30996 2346
08c2951c 2347(define_expand "udivmodsi4"
70252580
MM
2348 [(set (match_operand:SI 0 "register_operand" "=d")
2349 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2350 (match_operand:SI 2 "register_operand" "d")))
2351 (set (match_operand:SI 3 "register_operand" "=d")
2352 (umod:SI (match_dup 1)
2353 (match_dup 2)))
46299de9 2354 (clobber (match_scratch:SI 4 "=l"))
225b8835
ILT
2355 (clobber (match_scratch:SI 5 "=h"))
2356 (clobber (match_scratch:SI 6 "=a"))]
34b650b3 2357 "optimize"
08c2951c 2358 "
8ef30996 2359{
08c2951c
SC
2360 emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2361 operands[3]));
2362 if (!TARGET_NO_CHECK_ZERO_DIV)
2363 {
2364 emit_insn (gen_div_trap (operands[2],
1feed51c 2365 GEN_INT (0),
08c2951c
SC
2366 GEN_INT (0x7)));
2367 }
2368
2369 DONE;
2370}")
8ef30996 2371
08c2951c
SC
2372(define_insn "udivmodsi4_internal"
2373 [(set (match_operand:SI 0 "register_operand" "=l")
2374 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2375 (match_operand:SI 2 "register_operand" "d")))
2376 (set (match_operand:SI 3 "register_operand" "=h")
2377 (umod:SI (match_dup 1)
2378 (match_dup 2)))
c77e04ae 2379 (clobber (match_scratch:SI 4 "=a"))]
08c2951c
SC
2380 "optimize"
2381 "divu\\t$0,%1,%2"
8ef30996 2382 [(set_attr "type" "idiv")
0ff83799 2383 (set_attr "mode" "SI")])
bb621ad7 2384
08c2951c 2385(define_expand "udivmoddi4"
bb621ad7 2386 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
2387 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2388 (match_operand:DI 2 "se_register_operand" "d")))
bb621ad7
JW
2389 (set (match_operand:DI 3 "register_operand" "=d")
2390 (umod:DI (match_dup 1)
2391 (match_dup 2)))
46299de9 2392 (clobber (match_scratch:DI 4 "=l"))
225b8835
ILT
2393 (clobber (match_scratch:DI 5 "=h"))
2394 (clobber (match_scratch:DI 6 "=a"))]
bb621ad7 2395 "TARGET_64BIT && optimize"
08c2951c 2396 "
bb621ad7 2397{
08c2951c
SC
2398 emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2399 operands[3]));
2400 if (!TARGET_NO_CHECK_ZERO_DIV)
2401 {
2402 emit_insn (gen_div_trap (operands[2],
1feed51c 2403 GEN_INT (0),
08c2951c
SC
2404 GEN_INT (0x7)));
2405 }
2406
2407 DONE;
2408}")
bb621ad7 2409
08c2951c
SC
2410(define_insn "udivmoddi4_internal"
2411 [(set (match_operand:DI 0 "register_operand" "=l")
2412 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2413 (match_operand:DI 2 "se_register_operand" "d")))
2414 (set (match_operand:DI 3 "register_operand" "=h")
2415 (umod:DI (match_dup 1)
2416 (match_dup 2)))
c77e04ae 2417 (clobber (match_scratch:DI 4 "=a"))]
08c2951c
SC
2418 "TARGET_64BIT && optimize"
2419 "ddivu\\t$0,%1,%2"
2420 [(set_attr "type" "idiv")
0ff83799 2421 (set_attr "mode" "SI")])
08c2951c
SC
2422
2423;; Division trap
bb621ad7 2424
aa7ecb4a 2425(define_expand "div_trap"
08c2951c 2426 [(trap_if (eq (match_operand 0 "register_operand" "d")
def72bd2 2427 (match_operand 1 "true_reg_or_0_operand" "dJ"))
08c2951c
SC
2428 (match_operand 2 "immediate_operand" ""))]
2429 ""
aa7ecb4a
GRK
2430 "
2431{
2432 if (TARGET_MIPS16)
2433 emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2434 else
2435 emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2436 DONE;
2437}")
2438
2439(define_insn "div_trap_normal"
8f8b5612
GK
2440 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2441 (match_operand 1 "true_reg_or_0_operand" "d,J"))
aa7ecb4a
GRK
2442 (match_operand 2 "immediate_operand" ""))]
2443 "!TARGET_MIPS16"
08c2951c
SC
2444 "*
2445{
2446 rtx link;
2447 int have_dep_anti = 0;
2448
2449 /* For divmod if one division is not needed then we don't need an extra
2450 divide by zero trap, which is anti dependent on previous trap */
2451 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2452
2453 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
487f99d2 2454 && GET_CODE (XEXP (link, 0)) == INSN
08c2951c 2455 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
8f8b5612 2456 && which_alternative == 1)
08c2951c
SC
2457 have_dep_anti = 1;
2458 if (! have_dep_anti)
b151501e
JL
2459 {
2460 if (GENERATE_BRANCHLIKELY)
2461 {
8f8b5612 2462 if (which_alternative == 1)
efa3896a 2463 return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e 2464 else
efa3896a 2465 return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e
JL
2466 }
2467 else
2468 {
8f8b5612 2469 if (which_alternative == 1)
efa3896a 2470 return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e 2471 else
efa3896a 2472 return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
b151501e
JL
2473 }
2474 }
8da31fc1 2475 return \"\";
bb621ad7 2476}"
08c2951c 2477 [(set_attr "type" "unknown")
0ff83799 2478 (set_attr "length" "12")])
aa7ecb4a
GRK
2479
2480
2481;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2482
2483(define_insn "div_trap_mips16"
8f8b5612
GK
2484 [(trap_if (eq (match_operand 0 "register_operand" "d,d")
2485 (match_operand 1 "true_reg_or_0_operand" "d,J"))
aa7ecb4a
GRK
2486 (match_operand 2 "immediate_operand" ""))
2487 (clobber (reg:SI 24))]
2488 "TARGET_MIPS16"
2489 "*
2490{
2491 rtx link;
2492 int have_dep_anti = 0;
2493
2494 /* For divmod if one division is not needed then we don't need an extra
2495 divide by zero trap, which is anti dependent on previous trap */
2496 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2497
2498 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
487f99d2 2499 && GET_CODE (XEXP (link, 0)) == INSN
aa7ecb4a 2500 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
8f8b5612 2501 && which_alternative == 1)
aa7ecb4a
GRK
2502 have_dep_anti = 1;
2503 if (! have_dep_anti)
2504 {
6ebec6ee 2505 /* No branch delay slots on mips16. */
8f8b5612 2506 if (which_alternative == 1)
efa3896a 2507 return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
aa7ecb4a 2508 else
efa3896a 2509 return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
aa7ecb4a
GRK
2510 }
2511 return \"\";
2512}"
2513 [(set_attr "type" "unknown")
0ff83799 2514 (set_attr "length" "12")])
8ef30996 2515
7e07e3ba 2516(define_expand "divsi3"
08c2951c 2517 [(set (match_operand:SI 0 "register_operand" "=l")
8ef30996 2518 (div:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
2519 (match_operand:SI 2 "register_operand" "d")))
2520 (clobber (match_scratch:SI 3 "=h"))
2521 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 2522 "!optimize"
7e07e3ba
GK
2523 "
2524{
08c2951c
SC
2525 emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2526 if (!TARGET_NO_CHECK_ZERO_DIV)
2527 {
2528 emit_insn (gen_div_trap (operands[2],
1feed51c 2529 GEN_INT (0),
08c2951c
SC
2530 GEN_INT (0x7)));
2531 }
2532 if (TARGET_CHECK_RANGE_DIV)
2533 {
2534 emit_insn (gen_div_trap (operands[2],
2535 copy_to_mode_reg (SImode, GEN_INT (-1)),
2536 GEN_INT (0x6)));
2537 emit_insn (gen_div_trap (operands[2],
3a6ee9f4 2538 copy_to_mode_reg (SImode, GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2539 GEN_INT (0x6)));
2540 }
2541
2542 DONE;
7e07e3ba
GK
2543}")
2544
2545(define_insn "divsi3_internal"
08c2951c 2546 [(set (match_operand:SI 0 "register_operand" "=l")
7e07e3ba 2547 (div:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
2548 (match_operand:SI 2 "nonmemory_operand" "di")))
2549 (clobber (match_scratch:SI 3 "=h"))
2550 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2551 "!optimize"
08c2951c 2552 "div\\t$0,%1,%2"
8ef30996 2553 [(set_attr "type" "idiv")
0ff83799 2554 (set_attr "mode" "SI")])
8ef30996 2555
7e07e3ba 2556(define_expand "divdi3"
08c2951c 2557 [(set (match_operand:DI 0 "register_operand" "=l")
1908a152 2558 (div:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c
SC
2559 (match_operand:DI 2 "se_register_operand" "d")))
2560 (clobber (match_scratch:DI 3 "=h"))
2561 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 2562 "TARGET_64BIT && !optimize"
7e07e3ba
GK
2563 "
2564{
08c2951c
SC
2565 emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2566 if (!TARGET_NO_CHECK_ZERO_DIV)
2567 {
2568 emit_insn (gen_div_trap (operands[2],
1feed51c 2569 GEN_INT (0),
08c2951c
SC
2570 GEN_INT (0x7)));
2571 }
2572 if (TARGET_CHECK_RANGE_DIV)
2573 {
2574 emit_insn (gen_div_trap (operands[2],
2575 copy_to_mode_reg (DImode, GEN_INT (-1)),
2576 GEN_INT (0x6)));
2577 emit_insn (gen_div_trap (operands[2],
3a6ee9f4 2578 copy_to_mode_reg (DImode, GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2579 GEN_INT (0x6)));
2580 }
2581
2582 DONE;
7e07e3ba
GK
2583}")
2584
2585(define_insn "divdi3_internal"
08c2951c 2586 [(set (match_operand:DI 0 "register_operand" "=l")
7e07e3ba 2587 (div:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c
SC
2588 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2589 (clobber (match_scratch:SI 3 "=h"))
2590 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2591 "TARGET_64BIT && !optimize"
08c2951c 2592 "ddiv\\t$0,%1,%2"
bb621ad7 2593 [(set_attr "type" "idiv")
0ff83799 2594 (set_attr "mode" "DI")])
bb621ad7 2595
7e07e3ba 2596(define_expand "modsi3"
08c2951c 2597 [(set (match_operand:SI 0 "register_operand" "=h")
8ef30996 2598 (mod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c 2599 (match_operand:SI 2 "register_operand" "d")))
46299de9 2600 (clobber (match_scratch:SI 3 "=l"))
08c2951c 2601 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 2602 "!optimize"
7e07e3ba
GK
2603 "
2604{
08c2951c
SC
2605 emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2606 if (!TARGET_NO_CHECK_ZERO_DIV)
2607 {
2608 emit_insn (gen_div_trap (operands[2],
1feed51c 2609 GEN_INT (0),
08c2951c
SC
2610 GEN_INT (0x7)));
2611 }
2612 if (TARGET_CHECK_RANGE_DIV)
2613 {
2614 emit_insn (gen_div_trap (operands[2],
2615 copy_to_mode_reg (SImode, GEN_INT (-1)),
2616 GEN_INT (0x6)));
2617 emit_insn (gen_div_trap (operands[2],
3a6ee9f4 2618 copy_to_mode_reg (SImode, GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2619 GEN_INT (0x6)));
2620 }
2621
2622 DONE;
7e07e3ba
GK
2623}")
2624
2625(define_insn "modsi3_internal"
08c2951c 2626 [(set (match_operand:SI 0 "register_operand" "=h")
7e07e3ba 2627 (mod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
2628 (match_operand:SI 2 "nonmemory_operand" "di")))
2629 (clobber (match_scratch:SI 3 "=l"))
2630 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2631 "!optimize"
08c2951c 2632 "div\\t$0,%1,%2"
8ef30996 2633 [(set_attr "type" "idiv")
0ff83799 2634 (set_attr "mode" "SI")])
bb621ad7 2635
7e07e3ba 2636(define_expand "moddi3"
08c2951c 2637 [(set (match_operand:DI 0 "register_operand" "=h")
1908a152 2638 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c 2639 (match_operand:DI 2 "se_register_operand" "d")))
46299de9 2640 (clobber (match_scratch:DI 3 "=l"))
08c2951c 2641 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 2642 "TARGET_64BIT && !optimize"
7e07e3ba
GK
2643 "
2644{
08c2951c
SC
2645 emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2646 if (!TARGET_NO_CHECK_ZERO_DIV)
2647 {
2648 emit_insn (gen_div_trap (operands[2],
1feed51c 2649 GEN_INT (0),
08c2951c
SC
2650 GEN_INT (0x7)));
2651 }
2652 if (TARGET_CHECK_RANGE_DIV)
2653 {
2654 emit_insn (gen_div_trap (operands[2],
2655 copy_to_mode_reg (DImode, GEN_INT (-1)),
2656 GEN_INT (0x6)));
2657 emit_insn (gen_div_trap (operands[2],
3a6ee9f4 2658 copy_to_mode_reg (DImode, GEN_INT (BITMASK_HIGH)),
08c2951c
SC
2659 GEN_INT (0x6)));
2660 }
2661
2662 DONE;
7e07e3ba
GK
2663}")
2664
2665(define_insn "moddi3_internal"
08c2951c 2666 [(set (match_operand:DI 0 "register_operand" "=h")
7e07e3ba 2667 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c
SC
2668 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2669 (clobber (match_scratch:SI 3 "=l"))
2670 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2671 "TARGET_64BIT && !optimize"
08c2951c 2672 "ddiv\\t$0,%1,%2"
bb621ad7 2673 [(set_attr "type" "idiv")
0ff83799 2674 (set_attr "mode" "DI")])
8ef30996 2675
7e07e3ba 2676(define_expand "udivsi3"
08c2951c 2677 [(set (match_operand:SI 0 "register_operand" "=l")
8ef30996 2678 (udiv:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
2679 (match_operand:SI 2 "register_operand" "d")))
2680 (clobber (match_scratch:SI 3 "=h"))
2681 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 2682 "!optimize"
7e07e3ba
GK
2683 "
2684{
08c2951c
SC
2685 emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2686 if (!TARGET_NO_CHECK_ZERO_DIV)
2687 {
2688 emit_insn (gen_div_trap (operands[2],
1feed51c 2689 GEN_INT (0),
08c2951c
SC
2690 GEN_INT (0x7)));
2691 }
2692
2693 DONE;
7e07e3ba
GK
2694}")
2695
2696(define_insn "udivsi3_internal"
08c2951c 2697 [(set (match_operand:SI 0 "register_operand" "=l")
7e07e3ba 2698 (udiv:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
2699 (match_operand:SI 2 "nonmemory_operand" "di")))
2700 (clobber (match_scratch:SI 3 "=h"))
2701 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2702 "!optimize"
08c2951c 2703 "divu\\t$0,%1,%2"
8ef30996 2704 [(set_attr "type" "idiv")
0ff83799 2705 (set_attr "mode" "SI")])
bb621ad7 2706
7e07e3ba 2707(define_expand "udivdi3"
08c2951c 2708 [(set (match_operand:DI 0 "register_operand" "=l")
1908a152 2709 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c
SC
2710 (match_operand:DI 2 "se_register_operand" "di")))
2711 (clobber (match_scratch:DI 3 "=h"))
2712 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 2713 "TARGET_64BIT && !optimize"
7e07e3ba
GK
2714 "
2715{
08c2951c
SC
2716 emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2717 if (!TARGET_NO_CHECK_ZERO_DIV)
2718 {
2719 emit_insn (gen_div_trap (operands[2],
1feed51c 2720 GEN_INT (0),
08c2951c
SC
2721 GEN_INT (0x7)));
2722 }
2723
2724 DONE;
7e07e3ba
GK
2725}")
2726
2727(define_insn "udivdi3_internal"
08c2951c 2728 [(set (match_operand:DI 0 "register_operand" "=l")
7e07e3ba 2729 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c
SC
2730 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2731 (clobber (match_scratch:SI 3 "=h"))
2732 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2733 "TARGET_64BIT && !optimize"
08c2951c 2734 "ddivu\\t$0,%1,%2"
bb621ad7 2735 [(set_attr "type" "idiv")
0ff83799 2736 (set_attr "mode" "DI")])
8ef30996 2737
7e07e3ba 2738(define_expand "umodsi3"
08c2951c 2739 [(set (match_operand:SI 0 "register_operand" "=h")
8ef30996 2740 (umod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c 2741 (match_operand:SI 2 "register_operand" "d")))
46299de9 2742 (clobber (match_scratch:SI 3 "=l"))
08c2951c 2743 (clobber (match_scratch:SI 4 "=a"))]
34b650b3 2744 "!optimize"
7e07e3ba
GK
2745 "
2746{
08c2951c
SC
2747 emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2748 if (!TARGET_NO_CHECK_ZERO_DIV)
2749 {
2750 emit_insn (gen_div_trap (operands[2],
1feed51c 2751 GEN_INT (0),
08c2951c
SC
2752 GEN_INT (0x7)));
2753 }
2754
2755 DONE;
7e07e3ba
GK
2756}")
2757
2758(define_insn "umodsi3_internal"
08c2951c 2759 [(set (match_operand:SI 0 "register_operand" "=h")
7e07e3ba 2760 (umod:SI (match_operand:SI 1 "register_operand" "d")
08c2951c
SC
2761 (match_operand:SI 2 "nonmemory_operand" "di")))
2762 (clobber (match_scratch:SI 3 "=l"))
2763 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2764 "!optimize"
08c2951c 2765 "divu\\t$0,%1,%2"
8ef30996 2766 [(set_attr "type" "idiv")
0ff83799 2767 (set_attr "mode" "SI")])
bb621ad7 2768
7e07e3ba 2769(define_expand "umoddi3"
08c2951c 2770 [(set (match_operand:DI 0 "register_operand" "=h")
1908a152 2771 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c 2772 (match_operand:DI 2 "se_register_operand" "di")))
46299de9 2773 (clobber (match_scratch:DI 3 "=l"))
08c2951c 2774 (clobber (match_scratch:DI 4 "=a"))]
bb621ad7 2775 "TARGET_64BIT && !optimize"
7e07e3ba
GK
2776 "
2777{
08c2951c
SC
2778 emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2779 if (!TARGET_NO_CHECK_ZERO_DIV)
2780 {
2781 emit_insn (gen_div_trap (operands[2],
1feed51c 2782 GEN_INT (0),
08c2951c
SC
2783 GEN_INT (0x7)));
2784 }
2785
2786 DONE;
7e07e3ba
GK
2787}")
2788
2789(define_insn "umoddi3_internal"
08c2951c 2790 [(set (match_operand:DI 0 "register_operand" "=h")
7e07e3ba 2791 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
08c2951c
SC
2792 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2793 (clobber (match_scratch:SI 3 "=l"))
2794 (clobber (match_scratch:SI 4 "=a"))]
7e07e3ba 2795 "TARGET_64BIT && !optimize"
08c2951c 2796 "ddivu\\t$0,%1,%2"
bb621ad7 2797 [(set_attr "type" "idiv")
0ff83799 2798 (set_attr "mode" "DI")])
8ef30996
MM
2799\f
2800;;
2801;; ....................
2802;;
2803;; SQUARE ROOT
2804;;
2805;; ....................
2806
2807(define_insn "sqrtdf2"
2808 [(set (match_operand:DF 0 "register_operand" "=f")
2809 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
46299de9 2810 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
8ef30996 2811 "sqrt.d\\t%0,%1"
bb621ad7 2812 [(set_attr "type" "fsqrt")
0ff83799 2813 (set_attr "mode" "DF")])
8ef30996
MM
2814
2815(define_insn "sqrtsf2"
2816 [(set (match_operand:SF 0 "register_operand" "=f")
2817 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2818 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2819 "sqrt.s\\t%0,%1"
bb621ad7 2820 [(set_attr "type" "fsqrt")
0ff83799 2821 (set_attr "mode" "SF")])
8ef30996 2822
b8eb88d0
ILT
2823(define_insn ""
2824 [(set (match_operand:DF 0 "register_operand" "=f")
2825 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2826 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
de6c5979 2827 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0
ILT
2828 "rsqrt.d\\t%0,%2"
2829 [(set_attr "type" "fsqrt")
0ff83799 2830 (set_attr "mode" "DF")])
b8eb88d0
ILT
2831
2832(define_insn ""
2833 [(set (match_operand:SF 0 "register_operand" "=f")
2834 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2835 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
de6c5979 2836 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
b8eb88d0
ILT
2837 "rsqrt.s\\t%0,%2"
2838 [(set_attr "type" "fsqrt")
0ff83799 2839 (set_attr "mode" "SF")])
b8eb88d0 2840
8ef30996
MM
2841\f
2842;;
2843;; ....................
2844;;
2845;; ABSOLUTE VALUE
2846;;
2847;; ....................
2848
2849;; Do not use the integer abs macro instruction, since that signals an
2850;; exception on -2147483648 (sigh).
2851
2852(define_insn "abssi2"
2853 [(set (match_operand:SI 0 "register_operand" "=d")
2854 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2bcb2ab3 2855 "!TARGET_MIPS16"
8ef30996
MM
2856 "*
2857{
2858 dslots_jump_total++;
2859 dslots_jump_filled++;
2860 operands[2] = const0_rtx;
2861
bb621ad7
JW
2862 if (REGNO (operands[0]) == REGNO (operands[1]))
2863 {
e9a25f70 2864 if (GENERATE_BRANCHLIKELY)
efa3896a 2865 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
bb621ad7 2866 else
efa3896a 2867 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
bb621ad7
JW
2868 }
2869 else
efa3896a 2870 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
8ef30996
MM
2871}"
2872 [(set_attr "type" "multi")
2873 (set_attr "mode" "SI")
0ff83799 2874 (set_attr "length" "12")])
8ef30996 2875
bb621ad7
JW
2876(define_insn "absdi2"
2877 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 2878 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
2bcb2ab3 2879 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
2880 "*
2881{
404e4854 2882 unsigned int regno1;
bb621ad7
JW
2883 dslots_jump_total++;
2884 dslots_jump_filled++;
2885 operands[2] = const0_rtx;
12a345cd
CP
2886
2887 if (GET_CODE (operands[1]) == REG)
2888 regno1 = REGNO (operands[1]);
2889 else
2890 regno1 = REGNO (XEXP (operands[1], 0));
bb621ad7 2891
12a345cd 2892 if (REGNO (operands[0]) == regno1)
efa3896a 2893 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
bb621ad7 2894 else
efa3896a 2895 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
bb621ad7
JW
2896}"
2897 [(set_attr "type" "multi")
2898 (set_attr "mode" "DI")
0ff83799 2899 (set_attr "length" "12")])
bb621ad7 2900
8ef30996
MM
2901(define_insn "absdf2"
2902 [(set (match_operand:DF 0 "register_operand" "=f")
2903 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
46299de9 2904 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
2905 "abs.d\\t%0,%1"
2906 [(set_attr "type" "fabs")
0ff83799 2907 (set_attr "mode" "DF")])
8ef30996
MM
2908
2909(define_insn "abssf2"
2910 [(set (match_operand:SF 0 "register_operand" "=f")
2911 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2912 "TARGET_HARD_FLOAT"
2913 "abs.s\\t%0,%1"
2914 [(set_attr "type" "fabs")
0ff83799 2915 (set_attr "mode" "SF")])
8ef30996
MM
2916
2917\f
2918;;
2919;; ....................
2920;;
2921;; FIND FIRST BIT INSTRUCTION
2922;;
2923;; ....................
2924;;
2925
2926(define_insn "ffssi2"
2927 [(set (match_operand:SI 0 "register_operand" "=&d")
2928 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
7d87c851
MM
2929 (clobber (match_scratch:SI 2 "=&d"))
2930 (clobber (match_scratch:SI 3 "=&d"))]
2bcb2ab3 2931 "!TARGET_MIPS16"
8ef30996
MM
2932 "*
2933{
2934 dslots_jump_total += 2;
2935 dslots_jump_filled += 2;
2936 operands[4] = const0_rtx;
2937
2938 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2939 return \"%(\\
2940move\\t%0,%z4\\n\\
2941\\tbeq\\t%1,%z4,2f\\n\\
efa3896a 2942%~1:\\tand\\t%2,%1,0x0001\\n\\
8ef30996
MM
2943\\taddu\\t%0,%0,1\\n\\
2944\\tbeq\\t%2,%z4,1b\\n\\
2945\\tsrl\\t%1,%1,1\\n\\
efa3896a 2946%~2:%)\";
8ef30996
MM
2947
2948 return \"%(\\
2949move\\t%0,%z4\\n\\
2950\\tmove\\t%3,%1\\n\\
2951\\tbeq\\t%3,%z4,2f\\n\\
efa3896a 2952%~1:\\tand\\t%2,%3,0x0001\\n\\
8ef30996
MM
2953\\taddu\\t%0,%0,1\\n\\
2954\\tbeq\\t%2,%z4,1b\\n\\
2955\\tsrl\\t%3,%3,1\\n\\
efa3896a 2956%~2:%)\";
8ef30996
MM
2957}"
2958 [(set_attr "type" "multi")
2959 (set_attr "mode" "SI")
0ff83799 2960 (set_attr "length" "12")])
8ef30996 2961
bb621ad7
JW
2962(define_insn "ffsdi2"
2963 [(set (match_operand:DI 0 "register_operand" "=&d")
1908a152 2964 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
bb621ad7
JW
2965 (clobber (match_scratch:DI 2 "=&d"))
2966 (clobber (match_scratch:DI 3 "=&d"))]
2bcb2ab3 2967 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
2968 "*
2969{
2970 dslots_jump_total += 2;
2971 dslots_jump_filled += 2;
2972 operands[4] = const0_rtx;
2973
2974 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2975 return \"%(\\
2976move\\t%0,%z4\\n\\
2977\\tbeq\\t%1,%z4,2f\\n\\
efa3896a 2978%~1:\\tand\\t%2,%1,0x0001\\n\\
bb621ad7
JW
2979\\tdaddu\\t%0,%0,1\\n\\
2980\\tbeq\\t%2,%z4,1b\\n\\
2981\\tdsrl\\t%1,%1,1\\n\\
efa3896a 2982%~2:%)\";
bb621ad7
JW
2983
2984 return \"%(\\
2985move\\t%0,%z4\\n\\
2986\\tmove\\t%3,%1\\n\\
2987\\tbeq\\t%3,%z4,2f\\n\\
efa3896a 2988%~1:\\tand\\t%2,%3,0x0001\\n\\
bb621ad7
JW
2989\\tdaddu\\t%0,%0,1\\n\\
2990\\tbeq\\t%2,%z4,1b\\n\\
2991\\tdsrl\\t%3,%3,1\\n\\
efa3896a 2992%~2:%)\";
bb621ad7
JW
2993}"
2994 [(set_attr "type" "multi")
2995 (set_attr "mode" "DI")
0ff83799 2996 (set_attr "length" "24")])
bb621ad7 2997
8ef30996
MM
2998\f
2999;;
3000;; ....................
3001;;
3002;; NEGATION and ONE'S COMPLEMENT
3003;;
3004;; ....................
3005
3006(define_insn "negsi2"
3007 [(set (match_operand:SI 0 "register_operand" "=d")
3008 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
3009 ""
3010 "*
3011{
2bcb2ab3
GK
3012 if (TARGET_MIPS16)
3013 return \"neg\\t%0,%1\";
8ef30996
MM
3014 operands[2] = const0_rtx;
3015 return \"subu\\t%0,%z2,%1\";
3016}"
3017 [(set_attr "type" "arith")
0ff83799 3018 (set_attr "mode" "SI")])
8ef30996 3019
e7d7b3dc 3020(define_expand "negdi2"
8ef30996 3021 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 3022 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
8ef30996 3023 (clobber (match_dup 2))])]
2bcb2ab3 3024 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
bb621ad7
JW
3025 "
3026{
3027 if (TARGET_64BIT)
3028 {
3029 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
3030 DONE;
3031 }
3032
3033 operands[2] = gen_reg_rtx (SImode);
3034}")
8ef30996 3035
e7d7b3dc 3036(define_insn "negdi2_internal"
8ef30996
MM
3037 [(set (match_operand:DI 0 "register_operand" "=d")
3038 (neg:DI (match_operand:DI 1 "register_operand" "d")))
3039 (clobber (match_operand:SI 2 "register_operand" "=d"))]
2bcb2ab3 3040 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
3041 "*
3042{
3043 operands[3] = const0_rtx;
3044 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
3045}"
3046 [(set_attr "type" "darith")
3047 (set_attr "mode" "DI")
0ff83799 3048 (set_attr "length" "16")])
8ef30996 3049
bb621ad7
JW
3050(define_insn "negdi2_internal_2"
3051 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 3052 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
2bcb2ab3 3053 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3054 "*
3055{
3056 operands[2] = const0_rtx;
3057 return \"dsubu\\t%0,%z2,%1\";
3058}"
3059 [(set_attr "type" "arith")
0ff83799 3060 (set_attr "mode" "DI")])
bb621ad7 3061
8ef30996
MM
3062(define_insn "negdf2"
3063 [(set (match_operand:DF 0 "register_operand" "=f")
3064 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
46299de9 3065 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
3066 "neg.d\\t%0,%1"
3067 [(set_attr "type" "fneg")
0ff83799 3068 (set_attr "mode" "DF")])
8ef30996
MM
3069
3070(define_insn "negsf2"
3071 [(set (match_operand:SF 0 "register_operand" "=f")
3072 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3073 "TARGET_HARD_FLOAT"
3074 "neg.s\\t%0,%1"
3075 [(set_attr "type" "fneg")
0ff83799 3076 (set_attr "mode" "SF")])
8ef30996
MM
3077
3078(define_insn "one_cmplsi2"
3079 [(set (match_operand:SI 0 "register_operand" "=d")
3080 (not:SI (match_operand:SI 1 "register_operand" "d")))]
3081 ""
3082 "*
3083{
2bcb2ab3
GK
3084 if (TARGET_MIPS16)
3085 return \"not\\t%0,%1\";
8ef30996
MM
3086 operands[2] = const0_rtx;
3087 return \"nor\\t%0,%z2,%1\";
3088}"
3089 [(set_attr "type" "arith")
0ff83799 3090 (set_attr "mode" "SI")])
8ef30996
MM
3091
3092(define_insn "one_cmpldi2"
3093 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 3094 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
8ef30996
MM
3095 ""
3096 "*
3097{
2bcb2ab3
GK
3098 if (TARGET_MIPS16)
3099 {
3100 if (TARGET_64BIT)
3101 return \"not\\t%0,%1\";
3102 return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3103 }
8ef30996 3104 operands[2] = const0_rtx;
bb621ad7
JW
3105 if (TARGET_64BIT)
3106 return \"nor\\t%0,%z2,%1\";
8ef30996
MM
3107 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3108}"
3109 [(set_attr "type" "darith")
3110 (set_attr "mode" "DI")
bb621ad7
JW
3111 (set (attr "length")
3112 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
0ff83799
MM
3113 (const_int 4)
3114 (const_int 8)))])
8ef30996
MM
3115
3116(define_split
3117 [(set (match_operand:DI 0 "register_operand" "")
3118 (not:DI (match_operand:DI 1 "register_operand" "")))]
bb621ad7 3119 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3120 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3121 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3122
3123 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
ddef6bc7 3124 (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
8ef30996
MM
3125 "")
3126
8ef30996
MM
3127\f
3128;;
3129;; ....................
3130;;
3131;; LOGICAL
3132;;
3133;; ....................
3134;;
3135
2bcb2ab3
GK
3136;; Many of these instructions uses trivial define_expands, because we
3137;; want to use a different set of constraints when TARGET_MIPS16.
3138
3139(define_expand "andsi3"
65437fe8 3140 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
3141 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3142 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8 3143 ""
2bcb2ab3
GK
3144 "
3145{
3146 if (TARGET_MIPS16)
3147 operands[2] = force_reg (SImode, operands[2]);
3148}")
3149
3150(define_insn ""
3151 [(set (match_operand:SI 0 "register_operand" "=d,d")
3152 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3153 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3154 "!TARGET_MIPS16"
65437fe8
MM
3155 "@
3156 and\\t%0,%1,%2
3157 andi\\t%0,%1,%x2"
3158 [(set_attr "type" "arith")
0ff83799 3159 (set_attr "mode" "SI")])
65437fe8 3160
2bcb2ab3
GK
3161(define_insn ""
3162 [(set (match_operand:SI 0 "register_operand" "=d")
3163 (and:SI (match_operand:SI 1 "register_operand" "%0")
3164 (match_operand:SI 2 "register_operand" "d")))]
3165 "TARGET_MIPS16"
3166 "and\\t%0,%2"
3167 [(set_attr "type" "arith")
0ff83799 3168 (set_attr "mode" "SI")])
2bcb2ab3
GK
3169
3170(define_expand "anddi3"
8ef30996 3171 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
3172 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3173 (match_operand:DI 2 "se_register_operand" "d")))]
bb621ad7 3174 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2bcb2ab3
GK
3175 "
3176{
3177 if (TARGET_MIPS16)
3178 operands[2] = force_reg (DImode, operands[2]);
3179}")
3180
3181(define_insn ""
3182 [(set (match_operand:DI 0 "register_operand" "=d")
3183 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3184 (match_operand:DI 2 "se_register_operand" "d")))]
3185 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
bb621ad7
JW
3186 "*
3187{
3188 if (TARGET_64BIT)
3189 return \"and\\t%0,%1,%2\";
3190 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3191}"
8ef30996
MM
3192 [(set_attr "type" "darith")
3193 (set_attr "mode" "DI")
bb621ad7 3194 (set (attr "length")
77a8368e 3195 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
0ff83799
MM
3196 (const_int 4)
3197 (const_int 8)))])
8ef30996 3198
2bcb2ab3
GK
3199(define_insn ""
3200 [(set (match_operand:DI 0 "register_operand" "=d")
3201 (and:DI (match_operand:DI 1 "se_register_operand" "0")
3202 (match_operand:DI 2 "se_register_operand" "d")))]
3203 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3204 "*
3205{
3206 if (TARGET_64BIT)
3207 return \"and\\t%0,%2\";
3208 return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3209}"
3210 [(set_attr "type" "darith")
3211 (set_attr "mode" "DI")
3212 (set (attr "length")
3213 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
0ff83799
MM
3214 (const_int 4)
3215 (const_int 8)))])
2bcb2ab3 3216
8ef30996
MM
3217(define_split
3218 [(set (match_operand:DI 0 "register_operand" "")
3219 (and:DI (match_operand:DI 1 "register_operand" "")
3220 (match_operand:DI 2 "register_operand" "")))]
bb621ad7 3221 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3222 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3223 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3224 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3225
3226 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
ddef6bc7 3227 (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
8ef30996
MM
3228 "")
3229
bb621ad7
JW
3230(define_insn "anddi3_internal1"
3231 [(set (match_operand:DI 0 "register_operand" "=d,d")
1908a152
ILT
3232 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3233 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2bcb2ab3 3234 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3235 "@
3236 and\\t%0,%1,%2
3237 andi\\t%0,%1,%x2"
3238 [(set_attr "type" "arith")
0ff83799 3239 (set_attr "mode" "DI")])
bb621ad7 3240
2bcb2ab3 3241(define_expand "iorsi3"
65437fe8 3242 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
3243 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3244 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8 3245 ""
2bcb2ab3
GK
3246 "
3247{
3248 if (TARGET_MIPS16)
3249 operands[2] = force_reg (SImode, operands[2]);
3250}")
3251
3252(define_insn ""
3253 [(set (match_operand:SI 0 "register_operand" "=d,d")
3254 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3255 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3256 "!TARGET_MIPS16"
65437fe8
MM
3257 "@
3258 or\\t%0,%1,%2
3259 ori\\t%0,%1,%x2"
3260 [(set_attr "type" "arith")
0ff83799 3261 (set_attr "mode" "SI")])
65437fe8 3262
2bcb2ab3
GK
3263(define_insn ""
3264 [(set (match_operand:SI 0 "register_operand" "=d")
3265 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3266 (match_operand:SI 2 "register_operand" "d")))]
3267 "TARGET_MIPS16"
3268 "or\\t%0,%2"
3269 [(set_attr "type" "arith")
0ff83799 3270 (set_attr "mode" "SI")])
2bcb2ab3 3271
bb621ad7
JW
3272;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3273;;; TARGET_64BIT
3274
2bcb2ab3 3275(define_expand "iordi3"
8ef30996 3276 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
3277 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3278 (match_operand:DI 2 "se_register_operand" "d")))]
bb621ad7 3279 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2bcb2ab3
GK
3280 "")
3281
3282(define_insn ""
3283 [(set (match_operand:DI 0 "register_operand" "=d")
3284 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3285 (match_operand:DI 2 "se_register_operand" "d")))]
3286 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
bb621ad7
JW
3287 "*
3288{
3289 if (TARGET_64BIT)
3290 return \"or\\t%0,%1,%2\";
3291 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3292}"
8ef30996
MM
3293 [(set_attr "type" "darith")
3294 (set_attr "mode" "DI")
bb621ad7 3295 (set (attr "length")
77a8368e 3296 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
0ff83799
MM
3297 (const_int 4)
3298 (const_int 8)))])
8ef30996 3299
2bcb2ab3
GK
3300(define_insn ""
3301 [(set (match_operand:DI 0 "register_operand" "=d")
3302 (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3303 (match_operand:DI 2 "se_register_operand" "d")))]
3304 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3305 "*
3306{
3307 if (TARGET_64BIT)
3308 return \"or\\t%0,%2\";
3309 return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3310}"
3311 [(set_attr "type" "darith")
3312 (set_attr "mode" "DI")
3313 (set (attr "length")
3314 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
0ff83799
MM
3315 (const_int 4)
3316 (const_int 8)))])
2bcb2ab3 3317
8ef30996
MM
3318(define_split
3319 [(set (match_operand:DI 0 "register_operand" "")
3320 (ior:DI (match_operand:DI 1 "register_operand" "")
3321 (match_operand:DI 2 "register_operand" "")))]
bb621ad7 3322 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3323 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3324 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3325 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3326
3327 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
ddef6bc7 3328 (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
8ef30996
MM
3329 "")
3330
2bcb2ab3 3331(define_expand "xorsi3"
65437fe8 3332 [(set (match_operand:SI 0 "register_operand" "=d,d")
e2f2127c
MM
3333 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3334 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
65437fe8 3335 ""
2bcb2ab3
GK
3336 "")
3337
3338(define_insn ""
3339 [(set (match_operand:SI 0 "register_operand" "=d,d")
3340 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3341 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3342 "!TARGET_MIPS16"
65437fe8
MM
3343 "@
3344 xor\\t%0,%1,%2
3345 xori\\t%0,%1,%x2"
3346 [(set_attr "type" "arith")
0ff83799 3347 (set_attr "mode" "SI")])
65437fe8 3348
2bcb2ab3
GK
3349(define_insn ""
3350 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3351 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3352 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3353 "TARGET_MIPS16"
3354 "@
3355 xor\\t%0,%2
3356 cmpi\\t%1,%2
3357 cmp\\t%1,%2"
3358 [(set_attr "type" "arith")
3359 (set_attr "mode" "SI")
3360 (set_attr_alternative "length"
0ff83799 3361 [(const_int 4)
2bcb2ab3 3362 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
3363 (const_int 4)
3364 (const_int 8))
3365 (const_int 4)])])
2bcb2ab3 3366
bb621ad7
JW
3367;; ??? If delete the 32-bit long long patterns, then could merge this with
3368;; the following xordi3_internal pattern.
2bcb2ab3 3369(define_expand "xordi3"
8ef30996 3370 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
3371 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3372 (match_operand:DI 2 "se_register_operand" "d")))]
bb621ad7 3373 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2bcb2ab3
GK
3374 "")
3375
3376(define_insn ""
3377 [(set (match_operand:DI 0 "register_operand" "=d")
3378 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3379 (match_operand:DI 2 "se_register_operand" "d")))]
3380 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
bb621ad7
JW
3381 "*
3382{
3383 if (TARGET_64BIT)
3384 return \"xor\\t%0,%1,%2\";
3385 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3386}"
3387 [(set_attr "type" "darith")
8ef30996 3388 (set_attr "mode" "DI")
bb621ad7 3389 (set (attr "length")
77a8368e 3390 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
0ff83799
MM
3391 (const_int 4)
3392 (const_int 8)))])
8ef30996 3393
2bcb2ab3
GK
3394(define_insn ""
3395 [(set (match_operand:DI 0 "register_operand" "=d")
3396 (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3397 (match_operand:DI 2 "se_register_operand" "d")))]
3398 "!TARGET_64BIT && TARGET_MIPS16"
3399 "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3400 [(set_attr "type" "darith")
3401 (set_attr "mode" "DI")
0ff83799 3402 (set_attr "length" "8")])
2bcb2ab3
GK
3403
3404(define_insn ""
3405 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3406 (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3407 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3408 "TARGET_64BIT && TARGET_MIPS16"
3409 "@
3410 xor\\t%0,%2
3411 cmpi\\t%1,%2
3412 cmp\\t%1,%2"
3413 [(set_attr "type" "arith")
3414 (set_attr "mode" "DI")
3415 (set_attr_alternative "length"
0ff83799 3416 [(const_int 4)
2bcb2ab3 3417 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
3418 (const_int 4)
3419 (const_int 8))
3420 (const_int 4)])])
2bcb2ab3 3421
8ef30996
MM
3422(define_split
3423 [(set (match_operand:DI 0 "register_operand" "")
3424 (xor:DI (match_operand:DI 1 "register_operand" "")
3425 (match_operand:DI 2 "register_operand" "")))]
bb621ad7 3426 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
3427 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3428 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3429 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3430
3431 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
ddef6bc7 3432 (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
8ef30996
MM
3433 "")
3434
bb621ad7 3435(define_insn "xordi3_immed"
2bcb2ab3 3436 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
3437 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3438 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
2bcb2ab3 3439 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3440 "xori\\t%0,%1,%x2"
3441 [(set_attr "type" "arith")
0ff83799 3442 (set_attr "mode" "DI")])
bb621ad7 3443
77a8368e
JW
3444(define_insn "*norsi3"
3445 [(set (match_operand:SI 0 "register_operand" "=d")
3446 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3447 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2bcb2ab3 3448 "!TARGET_MIPS16"
77a8368e
JW
3449 "nor\\t%0,%z1,%z2"
3450 [(set_attr "type" "arith")
0ff83799 3451 (set_attr "mode" "SI")])
77a8368e
JW
3452
3453(define_insn "*nordi3"
3454 [(set (match_operand:DI 0 "register_operand" "=d")
3455 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3456 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
2bcb2ab3 3457 "!TARGET_MIPS16"
77a8368e
JW
3458 "*
3459{
3460 if (TARGET_64BIT)
3461 return \"nor\\t%0,%z1,%z2\";
3462 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3463}"
3464 [(set_attr "type" "darith")
3465 (set_attr "mode" "DI")
3466 (set (attr "length")
3467 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
0ff83799
MM
3468 (const_int 4)
3469 (const_int 8)))])
77a8368e
JW
3470
3471(define_split
3472 [(set (match_operand:DI 0 "register_operand" "")
3473 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3474 (not:DI (match_operand:DI 2 "register_operand" ""))))]
2bcb2ab3 3475 "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
77a8368e
JW
3476 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3477 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3478 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3479
3480 [(set (subreg:SI (match_dup 0) 0) (and:SI (not:SI (subreg:SI (match_dup 1) 0)) (not:SI (subreg:SI (match_dup 2) 0))))
ddef6bc7 3481 (set (subreg:SI (match_dup 0) 4) (and:SI (not:SI (subreg:SI (match_dup 1) 4)) (not:SI (subreg:SI (match_dup 2) 4))))]
77a8368e 3482 "")
8ef30996
MM
3483\f
3484;;
3485;; ....................
3486;;
3487;; TRUNCATION
3488;;
3489;; ....................
3490
3491(define_insn "truncdfsf2"
3492 [(set (match_operand:SF 0 "register_operand" "=f")
3493 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
46299de9 3494 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
3495 "cvt.s.d\\t%0,%1"
3496 [(set_attr "type" "fcvt")
0ff83799 3497 (set_attr "mode" "SF")])
8ef30996 3498
8894cf34
JW
3499(define_insn "truncdisi2"
3500 [(set (match_operand:SI 0 "register_operand" "=d")
1908a152 3501 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
bb621ad7 3502 "TARGET_64BIT"
2bcb2ab3
GK
3503 "*
3504{
3505 if (TARGET_MIPS16)
3506 return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3507 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3508}"
8894cf34
JW
3509 [(set_attr "type" "darith")
3510 (set_attr "mode" "SI")
2bcb2ab3 3511 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
0ff83799
MM
3512 (const_int 8)
3513 (const_int 16)))])
bb621ad7 3514
8894cf34
JW
3515(define_insn "truncdihi2"
3516 [(set (match_operand:HI 0 "register_operand" "=d")
1908a152 3517 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
00bb4b62
GK
3518 "TARGET_64BIT"
3519 "*
3520{
3521 if (TARGET_MIPS16)
3522 return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3523 return \"andi\\t%0,%1,0xffff\";
3524}"
8894cf34
JW
3525 [(set_attr "type" "darith")
3526 (set_attr "mode" "HI")
00bb4b62 3527 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
0ff83799
MM
3528 (const_int 4)
3529 (const_int 16)))])
8894cf34
JW
3530(define_insn "truncdiqi2"
3531 [(set (match_operand:QI 0 "register_operand" "=d")
1908a152 3532 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
00bb4b62
GK
3533 "TARGET_64BIT"
3534 "*
3535{
3536 if (TARGET_MIPS16)
3537 return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3538 return \"andi\\t%0,%1,0x00ff\";
3539}"
8894cf34
JW
3540 [(set_attr "type" "darith")
3541 (set_attr "mode" "QI")
00bb4b62 3542 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
0ff83799
MM
3543 (const_int 4)
3544 (const_int 16)))])
a67f7692
JW
3545
3546;; Combiner patterns to optimize shift/truncate combinations.
3547(define_insn ""
3548 [(set (match_operand:SI 0 "register_operand" "=d")
1908a152 3549 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
a67f7692 3550 (match_operand:DI 2 "small_int" "I"))))]
2bcb2ab3 3551 "TARGET_64BIT && !TARGET_MIPS16"
a67f7692
JW
3552 "*
3553{
3554 int shift_amt = INTVAL (operands[2]) & 0x3f;
3555
3556 if (shift_amt < 32)
3557 {
3558 operands[2] = GEN_INT (32 - shift_amt);
3559 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3560 }
3561 else
3562 {
3563 operands[2] = GEN_INT (shift_amt);
3564 return \"dsra\\t%0,%1,%2\";
3565 }
3566}"
3567 [(set_attr "type" "darith")
3568 (set_attr "mode" "SI")
0ff83799 3569 (set_attr "length" "8")])
a67f7692
JW
3570
3571(define_insn ""
3572 [(set (match_operand:SI 0 "register_operand" "=d")
1908a152 3573 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
a67f7692 3574 (match_operand:DI 2 "small_int" "I"))))]
2bcb2ab3 3575 "TARGET_64BIT && !TARGET_MIPS16"
a67f7692
JW
3576 "*
3577{
3578 int shift_amt = INTVAL (operands[2]) & 0x3f;
3579
3580 if (shift_amt < 32)
3581 {
3582 operands[2] = GEN_INT (32 - shift_amt);
3583 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3584 }
3585 else if (shift_amt == 32)
3586 return \"dsra\\t%0,%1,32\";
3587 else
3588 {
3589 operands[2] = GEN_INT (shift_amt);
3590 return \"dsrl\\t%0,%1,%2\";
3591 }
3592}"
3593 [(set_attr "type" "darith")
3594 (set_attr "mode" "SI")
0ff83799 3595 (set_attr "length" "8")])
a67f7692
JW
3596
3597(define_insn ""
3598 [(set (match_operand:SI 0 "register_operand" "=d")
1908a152 3599 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
a67f7692
JW
3600 (match_operand:DI 2 "small_int" "I"))))]
3601 "TARGET_64BIT"
3602 "*
3603{
3604 int shift_amt = INTVAL (operands[2]) & 0x3f;
3605
3606 if (shift_amt < 32)
3607 {
3608 operands[2] = GEN_INT (32 + shift_amt);
2bcb2ab3
GK
3609 if (TARGET_MIPS16)
3610 return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
a67f7692
JW
3611 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3612 }
3613 else
3614 return \"move\\t%0,%.\";
3615}"
3616 [(set_attr "type" "darith")
3617 (set_attr "mode" "SI")
0ff83799 3618 (set_attr "length" "8")])
99f762bf
JW
3619
3620;; Combiner patterns to optimize truncate/zero_extend combinations.
3621
3622(define_insn ""
3623 [(set (match_operand:SI 0 "register_operand" "=d")
3624 (zero_extend:SI (truncate:HI
1908a152 3625 (match_operand:DI 1 "se_register_operand" "d"))))]
2bcb2ab3 3626 "TARGET_64BIT && !TARGET_MIPS16"
99f762bf
JW
3627 "andi\\t%0,%1,0xffff"
3628 [(set_attr "type" "darith")
0ff83799 3629 (set_attr "mode" "SI")])
99f762bf
JW
3630
3631(define_insn ""
3632 [(set (match_operand:SI 0 "register_operand" "=d")
3633 (zero_extend:SI (truncate:QI
1908a152 3634 (match_operand:DI 1 "se_register_operand" "d"))))]
2bcb2ab3 3635 "TARGET_64BIT && !TARGET_MIPS16"
99f762bf
JW
3636 "andi\\t%0,%1,0xff"
3637 [(set_attr "type" "darith")
0ff83799 3638 (set_attr "mode" "SI")])
99f762bf
JW
3639
3640(define_insn ""
3641 [(set (match_operand:HI 0 "register_operand" "=d")
3642 (zero_extend:HI (truncate:QI
1908a152 3643 (match_operand:DI 1 "se_register_operand" "d"))))]
2bcb2ab3 3644 "TARGET_64BIT && !TARGET_MIPS16"
99f762bf
JW
3645 "andi\\t%0,%1,0xff"
3646 [(set_attr "type" "darith")
0ff83799 3647 (set_attr "mode" "HI")])
8ef30996
MM
3648\f
3649;;
3650;; ....................
3651;;
3652;; ZERO EXTENSION
3653;;
3654;; ....................
3655
3656;; Extension insns.
abdf3eea 3657;; Those for integer source operand are ordered widest source type first.
8ef30996 3658
bb621ad7
JW
3659(define_expand "zero_extendsidi2"
3660 [(set (match_operand:DI 0 "register_operand" "")
3661 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3662 "TARGET_64BIT"
3663 "
3664{
32fdad6e 3665 if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM)
bb621ad7
JW
3666 operands[1] = force_not_mem (operands[1]);
3667
3668 if (GET_CODE (operands[1]) != MEM)
3669 {
3670 rtx op1 = gen_lowpart (DImode, operands[1]);
3671 rtx temp = gen_reg_rtx (DImode);
95936d18 3672 rtx shift = GEN_INT (32);
bb621ad7
JW
3673
3674 emit_insn (gen_ashldi3 (temp, op1, shift));
3675 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3676 DONE;
3677 }
3678}")
3679
3680(define_insn "zero_extendsidi2_internal"
3681 [(set (match_operand:DI 0 "register_operand" "=d,d")
3682 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
b5031ab7 3683 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3684 "* return mips_move_1word (operands, insn, TRUE);"
3685 [(set_attr "type" "load")
3686 (set_attr "mode" "DI")
0ff83799 3687 (set_attr "length" "4,8")])
bb621ad7 3688
2bcb2ab3
GK
3689(define_expand "zero_extendhisi2"
3690 [(set (match_operand:SI 0 "register_operand" "")
3691 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3692 ""
3693 "
3694{
3695 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3696 {
3697 rtx op = gen_lowpart (SImode, operands[1]);
3698 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3699
3700 emit_insn (gen_andsi3 (operands[0], op, temp));
3701 DONE;
3702 }
3703}")
3704
3705(define_insn ""
8ef30996
MM
3706 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3707 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2bcb2ab3 3708 "!TARGET_MIPS16"
8ef30996
MM
3709 "*
3710{
3711 if (which_alternative == 0)
3712 return \"andi\\t%0,%1,0xffff\";
3713 else
3714 return mips_move_1word (operands, insn, TRUE);
3715}"
3716 [(set_attr "type" "arith,load,load")
92b4cee1 3717 (set_attr "mode" "SI")
0ff83799 3718 (set_attr "length" "4,4,8")])
8ef30996 3719
2bcb2ab3
GK
3720(define_insn ""
3721 [(set (match_operand:SI 0 "register_operand" "=d,d")
3722 (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3723 "TARGET_MIPS16"
3724 "* return mips_move_1word (operands, insn, TRUE);"
3725 [(set_attr "type" "load,load")
3726 (set_attr "mode" "SI")
0ff83799 3727 (set_attr "length" "4,8")])
2bcb2ab3
GK
3728
3729(define_expand "zero_extendhidi2"
3730 [(set (match_operand:DI 0 "register_operand" "")
3731 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3732 "TARGET_64BIT"
3733 "
3734{
3735 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3736 {
3737 rtx op = gen_lowpart (DImode, operands[1]);
3738 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3739
3740 emit_insn (gen_anddi3 (operands[0], op, temp));
3741 DONE;
3742 }
3743}")
3744
3745(define_insn ""
bb621ad7
JW
3746 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3747 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2bcb2ab3 3748 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3749 "*
3750{
3751 if (which_alternative == 0)
3752 return \"andi\\t%0,%1,0xffff\";
3753 else
3754 return mips_move_1word (operands, insn, TRUE);
3755}"
3756 [(set_attr "type" "arith,load,load")
3757 (set_attr "mode" "DI")
0ff83799 3758 (set_attr "length" "4,4,8")])
bb621ad7 3759
2bcb2ab3
GK
3760(define_insn ""
3761 [(set (match_operand:DI 0 "register_operand" "=d,d")
3762 (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3763 "TARGET_64BIT && TARGET_MIPS16"
3764 "* return mips_move_1word (operands, insn, TRUE);"
3765 [(set_attr "type" "load,load")
3766 (set_attr "mode" "DI")
0ff83799 3767 (set_attr "length" "4,8")])
2bcb2ab3
GK
3768
3769(define_expand "zero_extendqihi2"
3770 [(set (match_operand:HI 0 "register_operand" "")
3771 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3772 ""
3773 "
3774{
3775 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3776 {
3777 rtx op0 = gen_lowpart (SImode, operands[0]);
3778 rtx op1 = gen_lowpart (SImode, operands[1]);
3779 rtx temp = force_reg (SImode, GEN_INT (0xff));
3780
3781 emit_insn (gen_andsi3 (op0, op1, temp));
3782 DONE;
3783 }
3784}")
3785
3786(define_insn ""
8ef30996
MM
3787 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3788 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2bcb2ab3 3789 "!TARGET_MIPS16"
8ef30996
MM
3790 "*
3791{
3792 if (which_alternative == 0)
3793 return \"andi\\t%0,%1,0x00ff\";
3794 else
3795 return mips_move_1word (operands, insn, TRUE);
3796}"
3797 [(set_attr "type" "arith,load,load")
92b4cee1 3798 (set_attr "mode" "HI")
0ff83799 3799 (set_attr "length" "4,4,8")])
8ef30996 3800
2bcb2ab3
GK
3801(define_insn ""
3802 [(set (match_operand:HI 0 "register_operand" "=d,d")
3803 (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3804 "TARGET_MIPS16"
3805 "* return mips_move_1word (operands, insn, TRUE);"
3806 [(set_attr "type" "load,load")
3807 (set_attr "mode" "HI")
0ff83799 3808 (set_attr "length" "4,8")])
2bcb2ab3
GK
3809
3810(define_expand "zero_extendqisi2"
3811 [(set (match_operand:SI 0 "register_operand" "")
3812 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3813 ""
3814 "
3815{
3816 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3817 {
3818 rtx op = gen_lowpart (SImode, operands[1]);
3819 rtx temp = force_reg (SImode, GEN_INT (0xff));
3820
3821 emit_insn (gen_andsi3 (operands[0], op, temp));
3822 DONE;
3823 }
3824}")
3825
3826(define_insn ""
8ef30996
MM
3827 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3828 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2bcb2ab3 3829 "!TARGET_MIPS16"
8ef30996
MM
3830 "*
3831{
3832 if (which_alternative == 0)
3833 return \"andi\\t%0,%1,0x00ff\";
3834 else
3835 return mips_move_1word (operands, insn, TRUE);
3836}"
3837 [(set_attr "type" "arith,load,load")
92b4cee1 3838 (set_attr "mode" "SI")
0ff83799 3839 (set_attr "length" "4,4,8")])
8ef30996 3840
2bcb2ab3
GK
3841(define_insn ""
3842 [(set (match_operand:SI 0 "register_operand" "=d,d")
3843 (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3844 "TARGET_MIPS16"
3845 "* return mips_move_1word (operands, insn, TRUE);"
3846 [(set_attr "type" "load,load")
3847 (set_attr "mode" "SI")
0ff83799 3848 (set_attr "length" "4,8")])
2bcb2ab3
GK
3849
3850(define_expand "zero_extendqidi2"
3851 [(set (match_operand:DI 0 "register_operand" "")
3852 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3853 "TARGET_64BIT"
3854 "
3855{
3856 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3857 {
3858 rtx op = gen_lowpart (DImode, operands[1]);
3859 rtx temp = force_reg (DImode, GEN_INT (0xff));
3860
3861 emit_insn (gen_anddi3 (operands[0], op, temp));
3862 DONE;
3863 }
3864}")
3865
3866(define_insn ""
bb621ad7
JW
3867 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3868 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2bcb2ab3 3869 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
3870 "*
3871{
3872 if (which_alternative == 0)
3873 return \"andi\\t%0,%1,0x00ff\";
3874 else
3875 return mips_move_1word (operands, insn, TRUE);
3876}"
3877 [(set_attr "type" "arith,load,load")
3878 (set_attr "mode" "DI")
0ff83799 3879 (set_attr "length" "4,4,8")])
bb621ad7 3880
3cce8bc6
JW
3881;; These can be created when a paradoxical subreg operand with an implicit
3882;; sign_extend operator is reloaded. Because of the subreg, this is really
3883;; a zero extend.
3884;; ??? It might be possible to eliminate the need for these patterns by adding
3885;; more support to reload for implicit sign_extend operators.
3886(define_insn "*paradoxical_extendhidi2"
3887 [(set (match_operand:DI 0 "register_operand" "=d,d")
3888 (sign_extend:DI
3889 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
3890 "TARGET_64BIT"
3891 "*
3892{
3893 return mips_move_1word (operands, insn, TRUE);
3894}"
3895 [(set_attr "type" "load,load")
3896 (set_attr "mode" "DI")
0ff83799 3897 (set_attr "length" "4,8")])
3cce8bc6 3898
2bcb2ab3 3899(define_insn ""
3cce8bc6 3900 [(set (match_operand:DI 0 "register_operand" "=d,d")
2bcb2ab3
GK
3901 (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3902 "TARGET_64BIT && TARGET_MIPS16"
3903 "* return mips_move_1word (operands, insn, TRUE);"
3cce8bc6
JW
3904 [(set_attr "type" "load,load")
3905 (set_attr "mode" "DI")
0ff83799 3906 (set_attr "length" "4,8")])
8ef30996
MM
3907\f
3908;;
3909;; ....................
3910;;
3911;; SIGN EXTENSION
3912;;
3913;; ....................
3914
3915;; Extension insns.
abdf3eea 3916;; Those for integer source operand are ordered widest source type first.
8ef30996 3917
bbae0daa
ILT
3918;; In 64 bit mode, 32 bit values in general registers are always
3919;; correctly sign extended. That means that if the target is a
3920;; general register, we can sign extend from SImode to DImode just by
3921;; doing a move.
abdf3eea 3922
bbae0daa 3923(define_insn "extendsidi2"
2e72fa6a
GK
3924 [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
3925 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
abdf3eea
JW
3926 "TARGET_64BIT"
3927 "* return mips_move_1word (operands, insn, FALSE);"
2e72fa6a 3928 [(set_attr "type" "move,move,move,hilo,load,load")
bb621ad7 3929 (set_attr "mode" "DI")
0ff83799 3930 (set_attr "length" "4,4,4,4,4,8")])
bb621ad7 3931
8ef30996
MM
3932;; These patterns originally accepted general_operands, however, slightly
3933;; better code is generated by only accepting register_operands, and then
3934;; letting combine generate the lh and lb insns.
3935
bb621ad7
JW
3936(define_expand "extendhidi2"
3937 [(set (match_operand:DI 0 "register_operand" "")
3938 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3939 "TARGET_64BIT"
3940 "
3941{
3942 if (optimize && GET_CODE (operands[1]) == MEM)
3943 operands[1] = force_not_mem (operands[1]);
3944
3945 if (GET_CODE (operands[1]) != MEM)
3946 {
3947 rtx op1 = gen_lowpart (DImode, operands[1]);
3948 rtx temp = gen_reg_rtx (DImode);
95936d18 3949 rtx shift = GEN_INT (48);
bb621ad7
JW
3950
3951 emit_insn (gen_ashldi3 (temp, op1, shift));
3952 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3953 DONE;
3954 }
3955}")
3956
3957(define_insn "extendhidi2_internal"
3958 [(set (match_operand:DI 0 "register_operand" "=d,d")
3959 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3960 "TARGET_64BIT"
3961 "* return mips_move_1word (operands, insn, FALSE);"
3962 [(set_attr "type" "load")
3963 (set_attr "mode" "DI")
0ff83799 3964 (set_attr "length" "4,8")])
bb621ad7 3965
8ef30996
MM
3966(define_expand "extendhisi2"
3967 [(set (match_operand:SI 0 "register_operand" "")
3968 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3969 ""
3970 "
3971{
3972 if (optimize && GET_CODE (operands[1]) == MEM)
3973 operands[1] = force_not_mem (operands[1]);
3974
3975 if (GET_CODE (operands[1]) != MEM)
3976 {
3977 rtx op1 = gen_lowpart (SImode, operands[1]);
3978 rtx temp = gen_reg_rtx (SImode);
95936d18 3979 rtx shift = GEN_INT (16);
8ef30996
MM
3980
3981 emit_insn (gen_ashlsi3 (temp, op1, shift));
3982 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3983 DONE;
3984 }
3985}")
3986
3987(define_insn "extendhisi2_internal"
3988 [(set (match_operand:SI 0 "register_operand" "=d,d")
3989 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3990 ""
3991 "* return mips_move_1word (operands, insn, FALSE);"
92b4cee1
MM
3992 [(set_attr "type" "load")
3993 (set_attr "mode" "SI")
0ff83799 3994 (set_attr "length" "4,8")])
8ef30996
MM
3995
3996(define_expand "extendqihi2"
3997 [(set (match_operand:HI 0 "register_operand" "")
3998 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3999 ""
4000 "
4001{
4002 if (optimize && GET_CODE (operands[1]) == MEM)
4003 operands[1] = force_not_mem (operands[1]);
4004
4005 if (GET_CODE (operands[1]) != MEM)
4006 {
4007 rtx op0 = gen_lowpart (SImode, operands[0]);
4008 rtx op1 = gen_lowpart (SImode, operands[1]);
4009 rtx temp = gen_reg_rtx (SImode);
95936d18 4010 rtx shift = GEN_INT (24);
8ef30996
MM
4011
4012 emit_insn (gen_ashlsi3 (temp, op1, shift));
4013 emit_insn (gen_ashrsi3 (op0, temp, shift));
4014 DONE;
4015 }
4016}")
4017
4018(define_insn "extendqihi2_internal"
4019 [(set (match_operand:HI 0 "register_operand" "=d,d")
4020 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
4021 ""
4022 "* return mips_move_1word (operands, insn, FALSE);"
92b4cee1
MM
4023 [(set_attr "type" "load")
4024 (set_attr "mode" "SI")
0ff83799 4025 (set_attr "length" "4,8")])
8ef30996
MM
4026
4027
4028(define_expand "extendqisi2"
4029 [(set (match_operand:SI 0 "register_operand" "")
4030 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4031 ""
4032 "
4033{
4034 if (optimize && GET_CODE (operands[1]) == MEM)
4035 operands[1] = force_not_mem (operands[1]);
4036
4037 if (GET_CODE (operands[1]) != MEM)
4038 {
4039 rtx op1 = gen_lowpart (SImode, operands[1]);
4040 rtx temp = gen_reg_rtx (SImode);
95936d18 4041 rtx shift = GEN_INT (24);
8ef30996
MM
4042
4043 emit_insn (gen_ashlsi3 (temp, op1, shift));
4044 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
4045 DONE;
4046 }
4047}")
4048
4049(define_insn "extendqisi2_insn"
4050 [(set (match_operand:SI 0 "register_operand" "=d,d")
4051 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4052 ""
4053 "* return mips_move_1word (operands, insn, FALSE);"
92b4cee1
MM
4054 [(set_attr "type" "load")
4055 (set_attr "mode" "SI")
0ff83799 4056 (set_attr "length" "4,8")])
8ef30996 4057
bb621ad7
JW
4058(define_expand "extendqidi2"
4059 [(set (match_operand:DI 0 "register_operand" "")
4060 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4061 "TARGET_64BIT"
4062 "
4063{
4064 if (optimize && GET_CODE (operands[1]) == MEM)
4065 operands[1] = force_not_mem (operands[1]);
4066
4067 if (GET_CODE (operands[1]) != MEM)
4068 {
4069 rtx op1 = gen_lowpart (DImode, operands[1]);
4070 rtx temp = gen_reg_rtx (DImode);
95936d18 4071 rtx shift = GEN_INT (56);
bb621ad7
JW
4072
4073 emit_insn (gen_ashldi3 (temp, op1, shift));
4074 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4075 DONE;
4076 }
4077}")
4078
4079(define_insn "extendqidi2_insn"
4080 [(set (match_operand:DI 0 "register_operand" "=d,d")
4081 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4082 "TARGET_64BIT"
4083 "* return mips_move_1word (operands, insn, FALSE);"
4084 [(set_attr "type" "load")
4085 (set_attr "mode" "DI")
0ff83799 4086 (set_attr "length" "4,8")])
bb621ad7 4087
8ef30996
MM
4088
4089(define_insn "extendsfdf2"
4090 [(set (match_operand:DF 0 "register_operand" "=f")
4091 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
46299de9 4092 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4093 "cvt.d.s\\t%0,%1"
4094 [(set_attr "type" "fcvt")
0ff83799 4095 (set_attr "mode" "DF")])
8ef30996
MM
4096
4097\f
4098
4099;;
4100;; ....................
4101;;
4102;; CONVERSIONS
4103;;
4104;; ....................
4105
d1460eef
JW
4106;; The SImode scratch register can not be shared with address regs used for
4107;; operand zero, because then the address in the move instruction will be
4108;; clobbered. We mark the scratch register as early clobbered to prevent this.
4109
0609f021
JW
4110;; We need the ?X in alternative 1 so that it will be choosen only if the
4111;; destination is a floating point register. Otherwise, alternative 1 can
4112;; have lower cost than alternative 0 (because there is one less loser), and
4113;; can be choosen when it won't work (because integral reloads into FP
4114;; registers are not supported).
4115
c7343333 4116(define_insn "fix_truncdfsi2"
0e7e9155 4117 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
8ef30996 4118 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
d1460eef 4119 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
0609f021 4120 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
46299de9 4121 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4122 "*
4123{
4124 rtx xoperands[10];
4125
4126 if (which_alternative == 1)
4127 return \"trunc.w.d %0,%1,%2\";
4128
4129 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4130
4131 xoperands[0] = operands[0];
4132 xoperands[1] = operands[3];
4133 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4134 return \"\";
4135}"
92b4cee1
MM
4136 [(set_attr "type" "fcvt")
4137 (set_attr "mode" "DF")
0ff83799 4138 (set_attr "length" "44,36,40,44")])
8ef30996
MM
4139
4140
c7343333 4141(define_insn "fix_truncsfsi2"
0e7e9155 4142 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,*f,R,To")
8ef30996 4143 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
d1460eef 4144 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
0609f021 4145 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
8ef30996
MM
4146 "TARGET_HARD_FLOAT"
4147 "*
4148{
4149 rtx xoperands[10];
4150
4151 if (which_alternative == 1)
4152 return \"trunc.w.s %0,%1,%2\";
4153
4154 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4155
4156 xoperands[0] = operands[0];
4157 xoperands[1] = operands[3];
4158 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4159 return \"\";
4160}"
92b4cee1
MM
4161 [(set_attr "type" "fcvt")
4162 (set_attr "mode" "SF")
0ff83799 4163 (set_attr "length" "44,36,40,44")])
8ef30996
MM
4164
4165
bb621ad7
JW
4166;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4167;;; but not in the chapter that describes the FPU. It is not mentioned at all
4168;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4169
4170;;; Deleting this means that we now need two libgcc2.a libraries. One for
4171;;; the 32 bit calling convention and one for the 64 bit calling convention.
4172
4173;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4174
4175(define_insn "fix_truncdfdi2"
0e7e9155 4176 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
bb621ad7 4177 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
0609f021 4178 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
46299de9 4179 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
bb621ad7
JW
4180 "*
4181{
4182 rtx xoperands[10];
4183
4184 if (which_alternative == 1)
4185 return \"trunc.l.d %0,%1\";
4186
4187 output_asm_insn (\"trunc.l.d %2,%1\", operands);
4188
4189 xoperands[0] = operands[0];
4190 xoperands[1] = operands[2];
bd9f1972 4191 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
bb621ad7
JW
4192 return \"\";
4193}"
4194 [(set_attr "type" "fcvt")
4195 (set_attr "mode" "DF")
0ff83799 4196 (set_attr "length" "8,4,8,12")])
bb621ad7
JW
4197
4198
4199;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4200;;; but not in the chapter that describes the FPU. It is not mentioned at all
4201;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4202(define_insn "fix_truncsfdi2"
0e7e9155 4203 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,*f,R,To")
bb621ad7 4204 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
0609f021 4205 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
46299de9 4206 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
bb621ad7
JW
4207 "*
4208{
4209 rtx xoperands[10];
4210
4211 if (which_alternative == 1)
4212 return \"trunc.l.s %0,%1\";
4213
4214 output_asm_insn (\"trunc.l.s %2,%1\", operands);
4215
4216 xoperands[0] = operands[0];
4217 xoperands[1] = operands[2];
bd9f1972 4218 output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
bb621ad7
JW
4219 return \"\";
4220}"
4221 [(set_attr "type" "fcvt")
4222 (set_attr "mode" "SF")
0ff83799 4223 (set_attr "length" "8,4,8,12")])
bb621ad7
JW
4224
4225
8ef30996 4226(define_insn "floatsidf2"
bbdb5552
MM
4227 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4228 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
46299de9 4229 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
bbdb5552
MM
4230 "*
4231{
4232 dslots_load_total++;
4233 if (GET_CODE (operands[1]) == MEM)
5cccf78f 4234 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
bbdb5552
MM
4235
4236 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4237}"
92b4cee1
MM
4238 [(set_attr "type" "fcvt")
4239 (set_attr "mode" "DF")
0ff83799 4240 (set_attr "length" "12,16,12")])
8ef30996 4241
c7343333 4242
bb621ad7
JW
4243(define_insn "floatdidf2"
4244 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
1908a152 4245 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
46299de9 4246 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
bb621ad7
JW
4247 "*
4248{
4249 dslots_load_total++;
4250 if (GET_CODE (operands[1]) == MEM)
4251 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4252
4253 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4254}"
4255 [(set_attr "type" "fcvt")
4256 (set_attr "mode" "DF")
0ff83799 4257 (set_attr "length" "12,16,12")])
bb621ad7
JW
4258
4259
8ef30996 4260(define_insn "floatsisf2"
bbdb5552
MM
4261 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4262 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
8ef30996 4263 "TARGET_HARD_FLOAT"
bbdb5552
MM
4264 "*
4265{
4266 dslots_load_total++;
4267 if (GET_CODE (operands[1]) == MEM)
5cccf78f 4268 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
bbdb5552
MM
4269
4270 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4271}"
92b4cee1
MM
4272 [(set_attr "type" "fcvt")
4273 (set_attr "mode" "SF")
0ff83799 4274 (set_attr "length" "12,16,12")])
bbdb5552 4275
8ef30996 4276
bb621ad7
JW
4277(define_insn "floatdisf2"
4278 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
1908a152 4279 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
46299de9 4280 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
bb621ad7
JW
4281 "*
4282{
4283 dslots_load_total++;
4284 if (GET_CODE (operands[1]) == MEM)
4285 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4286
4287 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4288}"
4289 [(set_attr "type" "fcvt")
4290 (set_attr "mode" "SF")
0ff83799 4291 (set_attr "length" "12,16,12")])
bb621ad7
JW
4292
4293
8ef30996
MM
4294(define_expand "fixuns_truncdfsi2"
4295 [(set (match_operand:SI 0 "register_operand" "")
4296 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
46299de9 4297 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4298 "
4299{
4300 rtx reg1 = gen_reg_rtx (DFmode);
4301 rtx reg2 = gen_reg_rtx (DFmode);
4302 rtx reg3 = gen_reg_rtx (SImode);
4303 rtx label1 = gen_label_rtx ();
4304 rtx label2 = gen_label_rtx ();
4305 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4306
4307 if (reg1) /* turn off complaints about unreached code */
4308 {
8ef30996
MM
4309 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4310 do_pending_stack_adjust ();
4311
4312 emit_insn (gen_cmpdf (operands[1], reg1));
4313 emit_jump_insn (gen_bge (label1));
4314
4315 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
c5c76735
JL
4316 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4317 gen_rtx_LABEL_REF (VOIDmode, label2)));
8ef30996
MM
4318 emit_barrier ();
4319
4320 emit_label (label1);
c5c76735 4321 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3a6ee9f4 4322 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
8ef30996
MM
4323
4324 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4325 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4326
4327 emit_label (label2);
4328
4329 /* allow REG_NOTES to be set on last insn (labels don't have enough
4330 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4331 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8ef30996
MM
4332 DONE;
4333 }
4334}")
4335
c7343333 4336
bb621ad7
JW
4337(define_expand "fixuns_truncdfdi2"
4338 [(set (match_operand:DI 0 "register_operand" "")
4339 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
46299de9 4340 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
bb621ad7
JW
4341 "
4342{
4343 rtx reg1 = gen_reg_rtx (DFmode);
4344 rtx reg2 = gen_reg_rtx (DFmode);
4345 rtx reg3 = gen_reg_rtx (DImode);
4346 rtx label1 = gen_label_rtx ();
4347 rtx label2 = gen_label_rtx ();
4348 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4349
4350 if (reg1) /* turn off complaints about unreached code */
4351 {
4352 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4353 do_pending_stack_adjust ();
4354
4355 emit_insn (gen_cmpdf (operands[1], reg1));
4356 emit_jump_insn (gen_bge (label1));
4357
4358 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
c5c76735
JL
4359 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4360 gen_rtx_LABEL_REF (VOIDmode, label2)));
bb621ad7
JW
4361 emit_barrier ();
4362
4363 emit_label (label1);
c5c76735 4364 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3a6ee9f4 4365 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
bb621ad7
JW
4366 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4367
4368 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4369 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4370
4371 emit_label (label2);
4372
4373 /* allow REG_NOTES to be set on last insn (labels don't have enough
4374 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4375 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
bb621ad7
JW
4376 DONE;
4377 }
4378}")
4379
4380
8ef30996
MM
4381(define_expand "fixuns_truncsfsi2"
4382 [(set (match_operand:SI 0 "register_operand" "")
4383 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4384 "TARGET_HARD_FLOAT"
4385 "
4386{
4387 rtx reg1 = gen_reg_rtx (SFmode);
4388 rtx reg2 = gen_reg_rtx (SFmode);
4389 rtx reg3 = gen_reg_rtx (SImode);
4390 rtx label1 = gen_label_rtx ();
4391 rtx label2 = gen_label_rtx ();
4392 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4393
4394 if (reg1) /* turn off complaints about unreached code */
4395 {
8ef30996
MM
4396 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4397 do_pending_stack_adjust ();
4398
4399 emit_insn (gen_cmpsf (operands[1], reg1));
4400 emit_jump_insn (gen_bge (label1));
4401
4402 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
c5c76735
JL
4403 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4404 gen_rtx_LABEL_REF (VOIDmode, label2)));
8ef30996
MM
4405 emit_barrier ();
4406
4407 emit_label (label1);
c5c76735 4408 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3a6ee9f4 4409 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
8ef30996
MM
4410
4411 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4412 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4413
4414 emit_label (label2);
4415
4416 /* allow REG_NOTES to be set on last insn (labels don't have enough
4417 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4418 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8ef30996
MM
4419 DONE;
4420 }
4421}")
4422
8ef30996 4423
bb621ad7
JW
4424(define_expand "fixuns_truncsfdi2"
4425 [(set (match_operand:DI 0 "register_operand" "")
4426 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
46299de9 4427 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
4428 "
4429{
bb621ad7
JW
4430 rtx reg1 = gen_reg_rtx (SFmode);
4431 rtx reg2 = gen_reg_rtx (SFmode);
4432 rtx reg3 = gen_reg_rtx (DImode);
4433 rtx label1 = gen_label_rtx ();
4434 rtx label2 = gen_label_rtx ();
4435 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
8ef30996 4436
bb621ad7 4437 if (reg1) /* turn off complaints about unreached code */
8ef30996 4438 {
bb621ad7
JW
4439 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4440 do_pending_stack_adjust ();
8ef30996 4441
bb621ad7
JW
4442 emit_insn (gen_cmpsf (operands[1], reg1));
4443 emit_jump_insn (gen_bge (label1));
8ef30996 4444
bb621ad7 4445 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
c5c76735
JL
4446 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4447 gen_rtx_LABEL_REF (VOIDmode, label2)));
bb621ad7 4448 emit_barrier ();
8ef30996 4449
bb621ad7 4450 emit_label (label1);
c5c76735 4451 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3a6ee9f4 4452 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
bb621ad7 4453 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
8ef30996 4454
bb621ad7
JW
4455 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4456 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
8ef30996 4457
bb621ad7 4458 emit_label (label2);
8ef30996 4459
bb621ad7
JW
4460 /* allow REG_NOTES to be set on last insn (labels don't have enough
4461 fields, and can't be used for REG_NOTES anyway). */
c5c76735 4462 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
bb621ad7 4463 DONE;
8ef30996 4464 }
bb621ad7 4465}")
8ef30996 4466
bb621ad7
JW
4467\f
4468;;
4469;; ....................
4470;;
4471;; DATA MOVEMENT
4472;;
4473;; ....................
8ef30996 4474
c5563e11
JW
4475;; Bit field extract patterns which use lwl/lwr.
4476
c5563e11
JW
4477;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4478;; It isn't clear whether this will give better code.
4479
0d8e55d8 4480;; Only specify the mode operand 1, the rest are assumed to be word_mode.
c5563e11 4481(define_expand "extv"
0d8e55d8
JL
4482 [(set (match_operand 0 "register_operand" "")
4483 (sign_extract (match_operand:QI 1 "memory_operand" "")
4484 (match_operand 2 "immediate_operand" "")
4485 (match_operand 3 "immediate_operand" "")))]
2bcb2ab3 4486 "!TARGET_MIPS16"
c5563e11
JW
4487 "
4488{
0d8e55d8
JL
4489 /* If the field does not start on a byte boundary, then fail. */
4490 if (INTVAL (operands[3]) % 8 != 0)
4491 FAIL;
4492
4493 /* MIPS I and MIPS II can only handle a 32bit field. */
4494 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4495 FAIL;
4496
4497 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4498 if (TARGET_64BIT
4499 && INTVAL (operands[2]) != 64
4500 && INTVAL (operands[2]) != 32)
c5563e11
JW
4501 FAIL;
4502
4503 /* This can happen for a 64 bit target, when extracting a value from
4504 a 64 bit union member. extract_bit_field doesn't verify that our
4505 source matches the predicate, so we force it to be a MEM here. */
4506 if (GET_CODE (operands[1]) != MEM)
4507 FAIL;
8ef30996 4508
4911814e
JW
4509 /* Change the mode to BLKmode for aliasing purposes. */
4510 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4511
0d8e55d8
JL
4512 /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
4513 if (INTVAL (operands[2]) == 64)
4514 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4515 else
4516 {
4517 if (TARGET_64BIT)
4518 {
4519 operands[0] = gen_lowpart (SImode, operands[0]);
4520 if (operands[0] == NULL_RTX)
4521 FAIL;
4522 }
4523 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4524 }
c5563e11
JW
4525 DONE;
4526}")
4527
0d8e55d8 4528;; Only specify the mode operand 1, the rest are assumed to be word_mode.
c5563e11 4529(define_expand "extzv"
0d8e55d8
JL
4530 [(set (match_operand 0 "register_operand" "")
4531 (zero_extract (match_operand:QI 1 "memory_operand" "")
4532 (match_operand 2 "immediate_operand" "")
4533 (match_operand 3 "immediate_operand" "")))]
2bcb2ab3 4534 "!TARGET_MIPS16"
c5563e11
JW
4535 "
4536{
0d8e55d8
JL
4537 /* If the field does not start on a byte boundary, then fail. */
4538 if (INTVAL (operands[3]) % 8 != 0)
4539 FAIL;
4540
4541 /* MIPS I and MIPS II can only handle a 32bit field. */
4542 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4543 FAIL;
4544
4545 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4546 if (TARGET_64BIT
4547 && INTVAL (operands[2]) != 64
4548 && INTVAL (operands[2]) != 32)
c5563e11
JW
4549 FAIL;
4550
4551 /* This can happen for a 64 bit target, when extracting a value from
4552 a 64 bit union member. extract_bit_field doesn't verify that our
4553 source matches the predicate, so we force it to be a MEM here. */
4554 if (GET_CODE (operands[1]) != MEM)
4555 FAIL;
4556
4911814e
JW
4557 /* Change the mode to BLKmode for aliasing purposes. */
4558 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4559
c5563e11 4560 /* Otherwise, emit a lwl/lwr pair to load the value. */
0d8e55d8
JL
4561 if (INTVAL (operands[2]) == 64)
4562 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4563 else
4564 {
4565 if (TARGET_64BIT)
4566 {
4567 operands[0] = gen_lowpart (SImode, operands[0]);
4568 if (operands[0] == NULL_RTX)
4569 FAIL;
4570 }
4571 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4572 }
c5563e11
JW
4573 DONE;
4574}")
4575
0d8e55d8 4576;; Only specify the mode operands 0, the rest are assumed to be word_mode.
c5563e11 4577(define_expand "insv"
0d8e55d8
JL
4578 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4579 (match_operand 1 "immediate_operand" "")
4580 (match_operand 2 "immediate_operand" ""))
4581 (match_operand 3 "register_operand" ""))]
2bcb2ab3 4582 "!TARGET_MIPS16"
c5563e11
JW
4583 "
4584{
0d8e55d8
JL
4585 /* If the field does not start on a byte boundary, then fail. */
4586 if (INTVAL (operands[2]) % 8 != 0)
4587 FAIL;
4588
4589 /* MIPS I and MIPS II can only handle a 32bit field. */
4590 if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4591 FAIL;
4592
4593 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4594 if (TARGET_64BIT
4595 && INTVAL (operands[1]) != 64
4596 && INTVAL (operands[1]) != 32)
c5563e11
JW
4597 FAIL;
4598
4599 /* This can happen for a 64 bit target, when storing into a 32 bit union
4600 member. store_bit_field doesn't verify that our target matches the
4601 predicate, so we force it to be a MEM here. */
4602 if (GET_CODE (operands[0]) != MEM)
4603 FAIL;
4604
4911814e
JW
4605 /* Change the mode to BLKmode for aliasing purposes. */
4606 operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
4607
0d8e55d8
JL
4608 /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
4609 if (INTVAL (operands[1]) == 64)
4610 emit_insn (gen_movdi_usd (operands[0], operands[3]));
4611 else
4612 {
4613 if (TARGET_64BIT)
4614 {
4615 operands[3] = gen_lowpart (SImode, operands[3]);
4616 if (operands[3] == NULL_RTX)
4617 FAIL;
4618 }
4619 emit_insn (gen_movsi_usw (operands[0], operands[3]));
4620 }
c5563e11
JW
4621 DONE;
4622}")
4623
4624;; unaligned word moves generated by the bit field patterns
4625
4626(define_insn "movsi_ulw"
4627 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4911814e 4628 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
2bcb2ab3 4629 "!TARGET_MIPS16"
c5563e11
JW
4630 "*
4631{
4632 rtx offset = const0_rtx;
4633 rtx addr = XEXP (operands[1], 0);
4634 rtx mem_addr = eliminate_constant_term (addr, &offset);
e2fe6aba 4635 const char *ret;
c5563e11
JW
4636
4637 if (TARGET_STATS)
4638 mips_count_memory_refs (operands[1], 2);
4639
4640 /* The stack/frame pointers are always aligned, so we can convert
4641 to the faster lw if we are referencing an aligned stack location. */
4642
4643 if ((INTVAL (offset) & 3) == 0
4644 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4645 ret = \"lw\\t%0,%1\";
4646 else
4647 ret = \"ulw\\t%0,%1\";
4648
4649 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4650}"
4651 [(set_attr "type" "load,load")
4652 (set_attr "mode" "SI")
0ff83799 4653 (set_attr "length" "8,16")])
c5563e11
JW
4654
4655(define_insn "movsi_usw"
4911814e
JW
4656 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4657 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
2bcb2ab3 4658 "!TARGET_MIPS16"
c5563e11
JW
4659 "*
4660{
4661 rtx offset = const0_rtx;
4662 rtx addr = XEXP (operands[0], 0);
4663 rtx mem_addr = eliminate_constant_term (addr, &offset);
4664
4665 if (TARGET_STATS)
4666 mips_count_memory_refs (operands[0], 2);
4667
4668 /* The stack/frame pointers are always aligned, so we can convert
4669 to the faster sw if we are referencing an aligned stack location. */
4670
4671 if ((INTVAL (offset) & 3) == 0
4672 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
7ca3e713 4673 return \"sw\\t%z1,%0\";
c5563e11
JW
4674
4675 return \"usw\\t%z1,%0\";
4676}"
4677 [(set_attr "type" "store")
4678 (set_attr "mode" "SI")
0ff83799 4679 (set_attr "length" "8,16")])
ed50ab35 4680
0d8e55d8
JL
4681;; Bit field extract patterns which use ldl/ldr.
4682
4683;; unaligned double word moves generated by the bit field patterns
4684
4685(define_insn "movdi_uld"
4686 [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4687 (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4688 ""
4689 "*
4690{
4691 rtx offset = const0_rtx;
4692 rtx addr = XEXP (operands[1], 0);
4693 rtx mem_addr = eliminate_constant_term (addr, &offset);
e2fe6aba 4694 const char *ret;
0d8e55d8
JL
4695
4696 if (TARGET_STATS)
4697 mips_count_memory_refs (operands[1], 2);
4698
4699 /* The stack/frame pointers are always aligned, so we can convert
4700 to the faster lw if we are referencing an aligned stack location. */
4701
4702 if ((INTVAL (offset) & 7) == 0
4703 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4704 ret = \"ld\\t%0,%1\";
4705 else
4706 ret = \"uld\\t%0,%1\";
4707
4708 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4709}"
4710 [(set_attr "type" "load,load")
4711 (set_attr "mode" "SI")
0ff83799 4712 (set_attr "length" "8,16")])
0d8e55d8
JL
4713
4714(define_insn "movdi_usd"
4715 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4716 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4717 ""
4718 "*
4719{
4720 rtx offset = const0_rtx;
4721 rtx addr = XEXP (operands[0], 0);
4722 rtx mem_addr = eliminate_constant_term (addr, &offset);
4723
4724 if (TARGET_STATS)
4725 mips_count_memory_refs (operands[0], 2);
4726
4727 /* The stack/frame pointers are always aligned, so we can convert
4728 to the faster sw if we are referencing an aligned stack location. */
4729
4730 if ((INTVAL (offset) & 7) == 0
4731 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4732 return \"sd\\t%1,%0\";
4733
4734 return \"usd\\t%z1,%0\";
4735}"
4736 [(set_attr "type" "store")
4737 (set_attr "mode" "SI")
0ff83799 4738 (set_attr "length" "8,16")])
0d8e55d8 4739
aa4e54c4
JW
4740;; These two patterns support loading addresses with two instructions instead
4741;; of using the macro instruction la.
4742
4743;; ??? mips_move_1word has support for HIGH, so this pattern may be
4744;; unnecessary.
4745
4746(define_insn "high"
4747 [(set (match_operand:SI 0 "register_operand" "=r")
4748 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
2bcb2ab3 4749 "mips_split_addresses && !TARGET_MIPS16"
aa4e54c4 4750 "lui\\t%0,%%hi(%1) # high"
0ff83799 4751 [(set_attr "type" "move")])
aa4e54c4
JW
4752
4753(define_insn "low"
4754 [(set (match_operand:SI 0 "register_operand" "=r")
4755 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4756 (match_operand:SI 2 "immediate_operand" "")))]
2bcb2ab3 4757 "mips_split_addresses && !TARGET_MIPS16"
aa4e54c4
JW
4758 "addiu\\t%0,%1,%%lo(%2) # low"
4759 [(set_attr "type" "arith")
0ff83799 4760 (set_attr "mode" "SI")])
aa4e54c4 4761
8ef30996
MM
4762;; 64-bit integer moves
4763
4764;; Unlike most other insns, the move insns can't be split with
4765;; different predicates, because register spilling and other parts of
4766;; the compiler, have memoized the insn number already.
4767
ed50ab35
MM
4768(define_expand "movdi"
4769 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4770 (match_operand:DI 1 "general_operand" ""))]
4771 ""
4772 "
4773{
aa4e54c4
JW
4774 if (mips_split_addresses && mips_check_split (operands[1], DImode))
4775 {
4776 enum machine_mode mode = GET_MODE (operands[0]);
4777 rtx tem = ((reload_in_progress | reload_completed)
4778 ? operands[0] : gen_reg_rtx (mode));
4779
c5c76735
JL
4780 emit_insn (gen_rtx_SET (VOIDmode, tem,
4781 gen_rtx_HIGH (mode, operands[1])));
aa4e54c4 4782
c5c76735 4783 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
aa4e54c4
JW
4784 }
4785
e19ff60f
JW
4786 /* If we are generating embedded PIC code, and we are referring to a
4787 symbol in the .text section, we must use an offset from the start
4788 of the function. */
4789 if (TARGET_EMBEDDED_PIC
4790 && (GET_CODE (operands[1]) == LABEL_REF
4791 || (GET_CODE (operands[1]) == SYMBOL_REF
4792 && ! SYMBOL_REF_FLAG (operands[1]))))
4793 {
4794 rtx temp;
4795
4796 temp = embedded_pic_offset (operands[1]);
c5c76735
JL
4797 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
4798 force_reg (DImode, temp));
e19ff60f
JW
4799 emit_move_insn (operands[0], force_reg (DImode, temp));
4800 DONE;
4801 }
4802
4803 /* If operands[1] is a constant address illegal for pic, then we need to
4804 handle it just like LEGITIMIZE_ADDRESS does. */
4805 if (flag_pic && pic_address_needs_scratch (operands[1]))
4806 {
4807 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4808 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4809
4810 if (! SMALL_INT (temp2))
4811 temp2 = force_reg (DImode, temp2);
4812
c5c76735 4813 emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
e19ff60f
JW
4814 DONE;
4815 }
4816
2bcb2ab3
GK
4817 /* On the mips16, we can handle a GP relative reference by adding in
4818 $gp. We need to check the name to see whether this is a string
4819 constant. */
4820 if (TARGET_MIPS16
4821 && register_operand (operands[0], DImode)
4822 && GET_CODE (operands[1]) == SYMBOL_REF
4823 && SYMBOL_REF_FLAG (operands[1]))
4824 {
3cce094d 4825 const char *name = XSTR (operands[1], 0);
2bcb2ab3
GK
4826
4827 if (name[0] != '*'
4828 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4829 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4830 {
4831 rtx base_reg;
4832
4833 if (reload_in_progress || reload_completed)
4834 {
4835 /* In movsi we use the constant table here. However, in
4836 this case, we're better off copying $28 into a
4837 register and adding, because the constant table entry
4838 would be 8 bytes. */
4839 base_reg = operands[0];
4840 emit_move_insn (base_reg,
4841 gen_rtx (CONST, DImode,
4842 gen_rtx (REG, DImode,
4843 GP_REG_FIRST + 28)));
4844 }
4845 else
4846 {
4847 base_reg = gen_reg_rtx (Pmode);
4848 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4849 }
4850
4851 emit_move_insn (operands[0],
7e4e0956 4852 gen_rtx (PLUS, Pmode, base_reg,
2bcb2ab3
GK
4853 mips16_gp_offset (operands[1])));
4854 DONE;
4855 }
4856 }
4857
ed50ab35
MM
4858 if ((reload_in_progress | reload_completed) == 0
4859 && !register_operand (operands[0], DImode)
4860 && !register_operand (operands[1], DImode)
2bcb2ab3 4861 && (TARGET_MIPS16
6e92f4b6
KG
4862 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4863 && operands[1] != CONST0_RTX (DImode))))
ed50ab35
MM
4864 {
4865 rtx temp = force_reg (DImode, operands[1]);
4866 emit_move_insn (operands[0], temp);
4867 DONE;
4868 }
4869}")
4870
2bcb2ab3
GK
4871;; For mips16, we need a special case to handle storing $31 into
4872;; memory, since we don't have a constraint to match $31. This
4873;; instruction can be generated by save_restore_insns.
4874
4875(define_insn ""
0e7e9155 4876 [(set (match_operand:DI 0 "memory_operand" "=R,m")
2bcb2ab3
GK
4877 (reg:DI 31))]
4878 "TARGET_MIPS16 && TARGET_64BIT"
4879 "*
4880{
4881 operands[1] = gen_rtx (REG, DImode, 31);
4882 return mips_move_2words (operands, insn);
4883}"
4884 [(set_attr "type" "store")
4885 (set_attr "mode" "DI")
0ff83799 4886 (set_attr "length" "4,8")])
2bcb2ab3 4887
ed50ab35 4888(define_insn "movdi_internal"
c4eec192
JW
4889 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
4890 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
2bcb2ab3 4891 "!TARGET_64BIT && !TARGET_MIPS16
bb621ad7
JW
4892 && (register_operand (operands[0], DImode)
4893 || register_operand (operands[1], DImode)
4894 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4895 || operands[1] == CONST0_RTX (DImode))"
8ef30996 4896 "* return mips_move_2words (operands, insn); "
c4eec192 4897 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo")
92b4cee1 4898 (set_attr "mode" "DI")
0ff83799 4899 (set_attr "length" "8,16,8,16,8,16,8,8,8")])
8ef30996 4900
2bcb2ab3
GK
4901(define_insn ""
4902 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
4903 (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
4904 "!TARGET_64BIT && TARGET_MIPS16
4905 && (register_operand (operands[0], DImode)
4906 || register_operand (operands[1], DImode))"
4907 "* return mips_move_2words (operands, insn);"
4908 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
4909 (set_attr "mode" "DI")
0ff83799 4910 (set_attr "length" "8,8,8,8,12,8,16,8,16,8")])
2bcb2ab3 4911
8ef30996
MM
4912(define_split
4913 [(set (match_operand:DI 0 "register_operand" "")
4914 (match_operand:DI 1 "register_operand" ""))]
bb621ad7 4915 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
4916 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4917 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4918
4919 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
ddef6bc7 4920 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
8ef30996
MM
4921 "")
4922
bb621ad7 4923(define_insn "movdi_internal2"
c4eec192
JW
4924 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
4925 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
2bcb2ab3 4926 "TARGET_64BIT && !TARGET_MIPS16
bb621ad7 4927 && (register_operand (operands[0], DImode)
1908a152 4928 || se_register_operand (operands[1], DImode)
bb621ad7
JW
4929 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4930 || operands[1] == CONST0_RTX (DImode))"
4931 "* return mips_move_2words (operands, insn); "
c4eec192 4932 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
bb621ad7 4933 (set_attr "mode" "DI")
0ff83799 4934 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,8")])
225b8835 4935
2bcb2ab3
GK
4936(define_insn ""
4937 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
4938 (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
4939 "TARGET_64BIT && TARGET_MIPS16
4940 && (register_operand (operands[0], DImode)
4941 || se_register_operand (operands[1], DImode))"
4942 "* return mips_move_2words (operands, insn);"
4943 [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
4944 (set_attr "mode" "DI")
4945 (set_attr_alternative "length"
0ff83799
MM
4946 [(const_int 4)
4947 (const_int 4)
4948 (const_int 4)
2bcb2ab3 4949 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
4950 (const_int 4)
4951 (const_int 8))
2bcb2ab3 4952 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
4953 (const_int 8)
4954 (const_int 12))
2bcb2ab3 4955 (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
0ff83799
MM
4956 (const_int 4)
4957 (const_int 8))
4958 (const_int 4)
4959 (const_int 8)
4960 (const_int 4)
4961 (const_int 8)
4962 (const_int 4)])])
2bcb2ab3
GK
4963
4964;; On the mips16, we can split ld $r,N($r) into an add and a load,
4965;; when the original load is a 4 byte instruction but the add and the
4966;; load are 2 2 byte instructions.
4967
4968(define_split
4969 [(set (match_operand:DI 0 "register_operand" "")
4970 (mem:DI (plus:DI (match_dup 0)
4971 (match_operand:DI 1 "const_int_operand" ""))))]
4972 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4973 && GET_CODE (operands[0]) == REG
4974 && M16_REG_P (REGNO (operands[0]))
4975 && GET_CODE (operands[1]) == CONST_INT
4976 && ((INTVAL (operands[1]) < 0
4977 && INTVAL (operands[1]) >= -0x10)
4978 || (INTVAL (operands[1]) >= 32 * 8
4979 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4980 || (INTVAL (operands[1]) >= 0
4981 && INTVAL (operands[1]) < 32 * 8
4982 && (INTVAL (operands[1]) & 7) != 0))"
4983 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4984 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4985 "
4986{
4987 HOST_WIDE_INT val = INTVAL (operands[1]);
4988
4989 if (val < 0)
4990 operands[2] = GEN_INT (0);
4991 else if (val >= 32 * 8)
4992 {
4993 int off = val & 7;
4994
4995 operands[1] = GEN_INT (0x8 + off);
4996 operands[2] = GEN_INT (val - off - 0x8);
4997 }
4998 else
4999 {
5000 int off = val & 7;
5001
5002 operands[1] = GEN_INT (off);
5003 operands[2] = GEN_INT (val - off);
5004 }
5005}")
5006
225b8835
ILT
5007;; Handle input reloads in DImode.
5008;; This is mainly to handle reloading HILO_REGNUM. Note that we may
5009;; see it as the source or the destination, depending upon which way
5010;; reload handles the instruction.
5011;; Making the second operand TImode is a trick. The compiler may
5012;; reuse the same register for operand 0 and operand 2. Using TImode
5013;; gives us two registers, so we can always use the one which is not
5014;; used.
5015
5016(define_expand "reload_indi"
5017 [(set (match_operand:DI 0 "register_operand" "=b")
9ec36da5 5018 (match_operand:DI 1 "" "b"))
225b8835
ILT
5019 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5020 "TARGET_64BIT"
5021 "
5022{
c5c76735
JL
5023 rtx scratch = gen_rtx_REG (DImode,
5024 (REGNO (operands[0]) == REGNO (operands[2])
5025 ? REGNO (operands[2]) + 1
5026 : REGNO (operands[2])));
225b8835
ILT
5027
5028 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5029 {
5030 if (GET_CODE (operands[1]) == MEM)
5031 {
404e4854 5032 rtx memword, offword, hi_word, lo_word;
9ec36da5
JL
5033 rtx addr = find_replacement (&XEXP (operands[1], 0));
5034 rtx op1 = change_address (operands[1], VOIDmode, addr);
225b8835 5035
c5c76735 5036 scratch = gen_rtx_REG (SImode, REGNO (scratch));
9ec36da5
JL
5037 memword = change_address (op1, SImode, NULL_RTX);
5038 offword = change_address (adj_offsettable_operand (op1, 4),
225b8835
ILT
5039 SImode, NULL_RTX);
5040 if (BYTES_BIG_ENDIAN)
5041 {
404e4854
KG
5042 hi_word = memword;
5043 lo_word = offword;
225b8835
ILT
5044 }
5045 else
5046 {
404e4854
KG
5047 hi_word = offword;
5048 lo_word = memword;
225b8835 5049 }
404e4854 5050 emit_move_insn (scratch, hi_word);
c5c76735 5051 emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
404e4854 5052 emit_move_insn (scratch, lo_word);
225b8835 5053 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
839366dd 5054 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
225b8835
ILT
5055 }
5056 else
5057 {
5058 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
c5c76735 5059 emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
225b8835
ILT
5060 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5061 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5062 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
839366dd 5063 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
225b8835
ILT
5064 }
5065 DONE;
5066 }
5067 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5068 {
c5c76735 5069 emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
225b8835
ILT
5070 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5071 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
c5c76735 5072 emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
225b8835
ILT
5073 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5074 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
839366dd 5075 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
225b8835
ILT
5076 DONE;
5077 }
5078 /* This handles moves between a float register and HI/LO. */
5079 emit_move_insn (scratch, operands[1]);
5080 emit_move_insn (operands[0], scratch);
5081 DONE;
5082}")
bb621ad7 5083
225b8835
ILT
5084;; Handle output reloads in DImode.
5085
cf877a42
JW
5086;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5087;; use a TImode scratch reg.
5088
225b8835 5089(define_expand "reload_outdi"
9ec36da5 5090 [(set (match_operand:DI 0 "" "=b")
1908a152 5091 (match_operand:DI 1 "se_register_operand" "b"))
cf877a42 5092 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
225b8835
ILT
5093 "TARGET_64BIT"
5094 "
5095{
cf877a42
JW
5096 rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5097
225b8835
ILT
5098 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5099 {
cf877a42
JW
5100 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5101 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5102 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5103 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5104 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
839366dd 5105 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
225b8835
ILT
5106 DONE;
5107 }
5108 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5109 {
5110 if (GET_CODE (operands[0]) == MEM)
5111 {
404e4854 5112 rtx scratch, memword, offword, hi_word, lo_word;
9ec36da5
JL
5113 rtx addr = find_replacement (&XEXP (operands[0], 0));
5114 rtx op0 = change_address (operands[0], VOIDmode, addr);
225b8835 5115
c5c76735 5116 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
9ec36da5
JL
5117 memword = change_address (op0, SImode, NULL_RTX);
5118 offword = change_address (adj_offsettable_operand (op0, 4),
225b8835
ILT
5119 SImode, NULL_RTX);
5120 if (BYTES_BIG_ENDIAN)
5121 {
404e4854
KG
5122 hi_word = memword;
5123 lo_word = offword;
225b8835
ILT
5124 }
5125 else
5126 {
404e4854
KG
5127 hi_word = offword;
5128 lo_word = memword;
225b8835 5129 }
c5c76735 5130 emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
404e4854 5131 emit_move_insn (hi_word, scratch);
c5c76735 5132 emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
404e4854 5133 emit_move_insn (lo_word, scratch);
839366dd 5134 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
225b8835 5135 }
cf877a42
JW
5136 else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5137 {
5138 /* Handle the case where operand[0] is not a 'd' register,
5139 and hence we can not directly move from the HILO register
5140 into it. */
5141 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5142 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5143 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5144 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5145 emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5146 emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5147 emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5148 emit_insn (gen_movdi (operands[0], scratch));
839366dd 5149 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
cf877a42 5150 }
225b8835
ILT
5151 else
5152 {
cf877a42
JW
5153 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5154 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5155 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
225b8835
ILT
5156 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5157 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
cf877a42 5158 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
839366dd 5159 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
225b8835
ILT
5160 }
5161 DONE;
5162 }
5163 /* This handles moves between a float register and HI/LO. */
cf877a42
JW
5164 emit_move_insn (scratch, operands[1]);
5165 emit_move_insn (operands[0], scratch);
225b8835
ILT
5166 DONE;
5167}")
8ef30996
MM
5168
5169;; 32-bit Integer moves
5170
5171(define_split
5172 [(set (match_operand:SI 0 "register_operand" "")
5173 (match_operand:SI 1 "large_int" ""))]
2bcb2ab3 5174 "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996
MM
5175 [(set (match_dup 0)
5176 (match_dup 2))
5177 (set (match_dup 0)
5178 (ior:SI (match_dup 0)
5179 (match_dup 3)))]
5180 "
5181{
3a6ee9f4
MM
5182 operands[2] = GEN_INT (INTVAL (operands[1]) & BITMASK_UPPER16);
5183 operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
8ef30996
MM
5184}")
5185
5186;; Unlike most other insns, the move insns can't be split with
5187;; different predicates, because register spilling and other parts of
5188;; the compiler, have memoized the insn number already.
5189
f3b39eba
MM
5190(define_expand "movsi"
5191 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5192 (match_operand:SI 1 "general_operand" ""))]
5193 ""
ed50ab35
MM
5194 "
5195{
aa4e54c4
JW
5196 if (mips_split_addresses && mips_check_split (operands[1], SImode))
5197 {
5198 enum machine_mode mode = GET_MODE (operands[0]);
5199 rtx tem = ((reload_in_progress | reload_completed)
5200 ? operands[0] : gen_reg_rtx (mode));
5201
c5c76735
JL
5202 emit_insn (gen_rtx_SET (VOIDmode, tem,
5203 gen_rtx_HIGH (mode, operands[1])));
aa4e54c4 5204
c5c76735 5205 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
aa4e54c4
JW
5206 }
5207
92544bdf
ILT
5208 /* If we are generating embedded PIC code, and we are referring to a
5209 symbol in the .text section, we must use an offset from the start
5210 of the function. */
5211 if (TARGET_EMBEDDED_PIC
5212 && (GET_CODE (operands[1]) == LABEL_REF
5213 || (GET_CODE (operands[1]) == SYMBOL_REF
5214 && ! SYMBOL_REF_FLAG (operands[1]))))
5215 {
5216 rtx temp;
5217
5218 temp = embedded_pic_offset (operands[1]);
c5c76735
JL
5219 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
5220 force_reg (SImode, temp));
92544bdf
ILT
5221 emit_move_insn (operands[0], force_reg (SImode, temp));
5222 DONE;
5223 }
5224
3826a3da 5225 /* If operands[1] is a constant address invalid for pic, then we need to
5a5b76a2
JW
5226 handle it just like LEGITIMIZE_ADDRESS does. */
5227 if (flag_pic && pic_address_needs_scratch (operands[1]))
5228 {
5229 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5230 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5231
5232 if (! SMALL_INT (temp2))
5233 temp2 = force_reg (SImode, temp2);
5234
c5c76735 5235 emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
5a5b76a2
JW
5236 DONE;
5237 }
5238
2bcb2ab3
GK
5239 /* On the mips16, we can handle a GP relative reference by adding in
5240 $gp. We need to check the name to see whether this is a string
5241 constant. */
5242 if (TARGET_MIPS16
5243 && register_operand (operands[0], SImode)
5244 && GET_CODE (operands[1]) == SYMBOL_REF
5245 && SYMBOL_REF_FLAG (operands[1]))
5246 {
3cce094d 5247 const char *name = XSTR (operands[1], 0);
2bcb2ab3
GK
5248
5249 if (name[0] != '*'
5250 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5251 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5252 {
5253 rtx base_reg;
5254
5255 if (reload_in_progress || reload_completed)
5256 {
5257 /* We need to reload this address. In this case we
5258 aren't going to have a chance to combine loading the
5259 address with the load or store. That means that we
5260 can either generate a 2 byte move followed by a 4
5261 byte addition, or a 2 byte load with a 4 byte entry
5262 in the constant table. Since the entry in the
5263 constant table might be shared, we're better off, on
5264 average, loading the address from the constant table. */
5265 emit_move_insn (operands[0],
5266 force_const_mem (SImode, operands[1]));
5267 DONE;
5268 }
5269
5270 base_reg = gen_reg_rtx (Pmode);
5271 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5272
5273 emit_move_insn (operands[0],
7e4e0956 5274 gen_rtx (PLUS, Pmode, base_reg,
2bcb2ab3
GK
5275 mips16_gp_offset (operands[1])));
5276 DONE;
5277 }
5278 }
5279
ed50ab35
MM
5280 if ((reload_in_progress | reload_completed) == 0
5281 && !register_operand (operands[0], SImode)
5282 && !register_operand (operands[1], SImode)
2bcb2ab3
GK
5283 && (TARGET_MIPS16
5284 || GET_CODE (operands[1]) != CONST_INT
5285 || INTVAL (operands[1]) != 0))
ed50ab35
MM
5286 {
5287 rtx temp = force_reg (SImode, operands[1]);
5288 emit_move_insn (operands[0], temp);
5289 DONE;
5290 }
5291}")
f3b39eba 5292
2bcb2ab3
GK
5293;; For mips16, we need a special case to handle storing $31 into
5294;; memory, since we don't have a constraint to match $31. This
5295;; instruction can be generated by save_restore_insns.
5296
5297(define_insn ""
0e7e9155 5298 [(set (match_operand:SI 0 "memory_operand" "=R,m")
2bcb2ab3
GK
5299 (reg:SI 31))]
5300 "TARGET_MIPS16"
5301 "*
5302{
5303 operands[1] = gen_rtx (REG, SImode, 31);
5304 return mips_move_1word (operands, insn, FALSE);
5305}"
5306 [(set_attr "type" "store")
5307 (set_attr "mode" "SI")
0ff83799 5308 (set_attr "length" "4,8")])
2bcb2ab3 5309
0fb5ac6f
MM
5310;; The difference between these two is whether or not ints are allowed
5311;; in FP registers (off by default, use -mdebugh to enable).
5312
5313(define_insn "movsi_internal1"
225b8835 5314 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
c4eec192 5315 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a"))]
2bcb2ab3 5316 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
ed50ab35
MM
5317 && (register_operand (operands[0], SImode)
5318 || register_operand (operands[1], SImode)
5319 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
bb621ad7 5320 "* return mips_move_1word (operands, insn, FALSE);"
225b8835 5321 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
92b4cee1 5322 (set_attr "mode" "SI")
0ff83799 5323 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
8ef30996 5324
0fb5ac6f 5325(define_insn "movsi_internal2"
225b8835 5326 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
c4eec192 5327 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
2bcb2ab3 5328 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
ed50ab35
MM
5329 && (register_operand (operands[0], SImode)
5330 || register_operand (operands[1], SImode)
5331 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
bb621ad7 5332 "* return mips_move_1word (operands, insn, FALSE);"
225b8835 5333 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
0fb5ac6f 5334 (set_attr "mode" "SI")
0ff83799 5335 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,4,4")])
0fb5ac6f 5336
2bcb2ab3
GK
5337;; This is the mips16 movsi instruction. We accept a small integer as
5338;; the source if the destination is a GP memory reference. This is
5339;; because we want the combine pass to turn adding a GP reference to a
5340;; register into a direct GP reference, but the combine pass will pass
5341;; in the source as a constant if it finds an equivalent one. If the
5342;; instruction is recognized, reload will force the constant back out
5343;; into a register.
225b8835 5344
2bcb2ab3
GK
5345(define_insn ""
5346 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5347 (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5348 "TARGET_MIPS16
5349 && (register_operand (operands[0], SImode)
5350 || register_operand (operands[1], SImode)
5351 || (GET_CODE (operands[0]) == MEM
5352 && GET_CODE (XEXP (operands[0], 0)) == PLUS
5353 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5354 && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5355 && GET_CODE (operands[1]) == CONST_INT
5356 && (SMALL_INT (operands[1])
5357 || SMALL_INT_UNSIGNED (operands[1]))))"
5358 "* return mips_move_1word (operands, insn, FALSE);"
5359 [(set_attr "type" "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5360 (set_attr "mode" "SI")
5361 (set_attr_alternative "length"
0ff83799
MM
5362 [(const_int 4)
5363 (const_int 4)
5364 (const_int 4)
5365 (const_int 8)
2bcb2ab3 5366 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
5367 (const_int 4)
5368 (const_int 8))
2bcb2ab3 5369 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
5370 (const_int 8)
5371 (const_int 12))
2bcb2ab3 5372 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
0ff83799
MM
5373 (const_int 4)
5374 (const_int 8))
5375 (const_int 4)
5376 (const_int 8)
5377 (const_int 4)
5378 (const_int 8)
5379 (const_int 4)
5380 (const_int 4)])])
2bcb2ab3
GK
5381
5382;; On the mips16, we can split lw $r,N($r) into an add and a load,
5383;; when the original load is a 4 byte instruction but the add and the
5384;; load are 2 2 byte instructions.
5385
5386(define_split
5387 [(set (match_operand:SI 0 "register_operand" "")
5388 (mem:SI (plus:SI (match_dup 0)
5389 (match_operand:SI 1 "const_int_operand" ""))))]
5390 "TARGET_MIPS16 && reload_completed
5391 && GET_CODE (operands[0]) == REG
5392 && M16_REG_P (REGNO (operands[0]))
5393 && GET_CODE (operands[1]) == CONST_INT
5394 && ((INTVAL (operands[1]) < 0
5395 && INTVAL (operands[1]) >= -0x80)
5396 || (INTVAL (operands[1]) >= 32 * 4
5397 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5398 || (INTVAL (operands[1]) >= 0
5399 && INTVAL (operands[1]) < 32 * 4
5400 && (INTVAL (operands[1]) & 3) != 0))"
5401 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5402 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
225b8835
ILT
5403 "
5404{
2bcb2ab3
GK
5405 HOST_WIDE_INT val = INTVAL (operands[1]);
5406
5407 if (val < 0)
5408 operands[2] = GEN_INT (0);
5409 else if (val >= 32 * 4)
5410 {
5411 int off = val & 3;
5412
5413 operands[1] = GEN_INT (0x7c + off);
5414 operands[2] = GEN_INT (val - off - 0x7c);
5415 }
5416 else
5417 {
5418 int off = val & 3;
5419
5420 operands[1] = GEN_INT (off);
5421 operands[2] = GEN_INT (val - off);
5422 }
5423}")
5424
5425;; On the mips16, we can split a load of certain constants into a load
5426;; and an add. This turns a 4 byte instruction into 2 2 byte
5427;; instructions.
5428
5429(define_split
5430 [(set (match_operand:SI 0 "register_operand" "")
5431 (match_operand:SI 1 "const_int_operand" ""))]
5432 "TARGET_MIPS16 && reload_completed
5433 && GET_CODE (operands[0]) == REG
5434 && M16_REG_P (REGNO (operands[0]))
5435 && GET_CODE (operands[1]) == CONST_INT
5436 && INTVAL (operands[1]) >= 0x100
5437 && INTVAL (operands[1]) <= 0xff + 0x7f"
5438 [(set (match_dup 0) (match_dup 1))
5439 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5440 "
5441{
5442 int val = INTVAL (operands[1]);
5443
5444 operands[1] = GEN_INT (0xff);
5445 operands[2] = GEN_INT (val - 0xff);
5446}")
5447
5448;; On the mips16, we can split a load of a negative constant into a
5449;; load and a neg. That's what mips_move_1word will generate anyhow.
5450
5451(define_split
5452 [(set (match_operand:SI 0 "register_operand" "")
5453 (match_operand:SI 1 "const_int_operand" ""))]
5454 "TARGET_MIPS16 && reload_completed
5455 && GET_CODE (operands[0]) == REG
5456 && M16_REG_P (REGNO (operands[0]))
5457 && GET_CODE (operands[1]) == CONST_INT
5458 && INTVAL (operands[1]) < 0
5459 && INTVAL (operands[1]) > - 0x8000"
5460 [(set (match_dup 0) (match_dup 1))
5461 (set (match_dup 0) (neg:SI (match_dup 0)))]
5462 "
5463{
5464 operands[1] = GEN_INT (- INTVAL (operands[1]));
5465}")
5466
5467;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5468;; order to set the sign bit correctly in the HI register.
5469
5470(define_expand "reload_outsi"
5471 [(set (match_operand:SI 0 "general_operand" "=b")
5472 (match_operand:SI 1 "register_operand" "b"))
5473 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5474 "TARGET_64BIT || TARGET_MIPS16"
5475 "
5476{
5477 if (TARGET_64BIT
5478 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
225b8835 5479 {
c5c76735 5480 emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
225b8835
ILT
5481 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5482 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
839366dd 5483 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
225b8835
ILT
5484 DONE;
5485 }
2bcb2ab3
GK
5486 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5487 if (TARGET_MIPS16
5488 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5489 {
5490 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5491 /* This is gen_mulsi3_internal, but we need to fill in the
5492 scratch registers. */
5493 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5494 gen_rtvec (3,
5495 gen_rtx (SET, VOIDmode,
5496 operands[0],
5497 gen_rtx (MULT, SImode,
5498 operands[1],
5499 operands[2])),
5500 gen_rtx (CLOBBER, VOIDmode,
5501 gen_rtx (REG, SImode, 64)),
5502 gen_rtx (CLOBBER, VOIDmode,
5503 gen_rtx (REG, SImode, 66)))));
5504 DONE;
5505 }
5506 /* FIXME: I don't know how to get a value into the HI register. */
ca45b913
JW
5507 if (GET_CODE (operands[0]) == REG
5508 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5509 : GP_REG_P (REGNO (operands[0]))))
2bcb2ab3
GK
5510 {
5511 emit_move_insn (operands[0], operands[1]);
5512 DONE;
5513 }
225b8835
ILT
5514 /* This handles moves between a float register and HI/LO. */
5515 emit_move_insn (operands[2], operands[1]);
5516 emit_move_insn (operands[0], operands[2]);
5517 DONE;
5518}")
0fb5ac6f 5519
2bcb2ab3
GK
5520;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5521;; so we use a mult. ??? This is hideous, and we ought to figure out
5522;; something better.
5523
bf4f78ee
JW
5524;; We use no predicate for operand1, because it may be a PLUS, and there
5525;; is no convenient predicate for that.
5526
2bcb2ab3
GK
5527(define_expand "reload_insi"
5528 [(set (match_operand:SI 0 "register_operand" "=b")
bf4f78ee 5529 (match_operand:SI 1 "" "b"))
2bcb2ab3
GK
5530 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5531 "TARGET_MIPS16"
5532 "
5533{
5534 if (TARGET_MIPS16
5535 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5536 {
5537 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5538 /* This is gen_mulsi3_internal, but we need to fill in the
5539 scratch registers. */
5540 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5541 gen_rtvec (3,
5542 gen_rtx (SET, VOIDmode,
5543 operands[0],
5544 gen_rtx (MULT, SImode,
5545 operands[1],
5546 operands[2])),
5547 gen_rtx (CLOBBER, VOIDmode,
5548 gen_rtx (REG, SImode, 64)),
5549 gen_rtx (CLOBBER, VOIDmode,
5550 gen_rtx (REG, SImode, 66)))));
5551 DONE;
5552 }
bf4f78ee
JW
5553
5554 /* If this is a plus, then this must be an add of the stack pointer against
5555 either a hard register or a pseudo. */
5556 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5557 {
5558 rtx plus_op;
5559
5560 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5561 plus_op = XEXP (operands[1], 1);
5562 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5563 plus_op = XEXP (operands[1], 0);
5564 else
5565 abort ();
5566
5567 /* We should have a register now. */
5568 if (GET_CODE (plus_op) != REG)
5569 abort ();
5570
5571 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5572 {
5573 /* We have to have at least one temporary register which is not
5574 overlapping plus_op. */
5575 if (! rtx_equal_p (plus_op, operands[0]))
5576 {
5577 emit_move_insn (operands[0], stack_pointer_rtx);
5578 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5579 }
5580 else if (! rtx_equal_p (plus_op, operands[2]))
5581 {
5582 emit_move_insn (operands[2], stack_pointer_rtx);
5583 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5584 }
5585 else
5586 abort ();
5587 }
5588 else
5589 {
5590 /* We need two registers in this case. */
5591 if (! rtx_equal_p (operands[0], operands[2]))
5592 {
5593 emit_move_insn (operands[0], stack_pointer_rtx);
5594 emit_move_insn (operands[2], plus_op);
5595 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5596 }
5597 else
5598 abort ();
5599 }
5600 DONE;
5601 }
5602
2bcb2ab3
GK
5603 /* FIXME: I don't know how to get a value into the HI register. */
5604 emit_move_insn (operands[0], operands[1]);
5605 DONE;
5606}")
5607
b8eb88d0
ILT
5608;; This insn handles moving CCmode values. It's really just a
5609;; slightly simplified copy of movsi_internal2, with additional cases
5610;; to move a condition register to a general register and to move
5611;; between the general registers and the floating point registers.
5612
5613(define_insn "movcc"
5614 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5615 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
76ee8042 5616 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5617 "* return mips_move_1word (operands, insn, FALSE);"
5618 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5619 (set_attr "mode" "SI")
0ff83799 5620 (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
b8eb88d0
ILT
5621
5622;; Reload condition code registers. These need scratch registers.
5623
5624(define_expand "reload_incc"
5625 [(set (match_operand:CC 0 "register_operand" "=z")
5626 (match_operand:CC 1 "general_operand" "z"))
5627 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
76ee8042 5628 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5629 "
5630{
5631 rtx source;
5632 rtx fp1, fp2;
5633
5634 /* This is called when are copying some value into a condition code
5635 register. Operand 0 is the condition code register. Operand 1
5636 is the source. Operand 2 is a scratch register; we use TFmode
5637 because we actually need two floating point registers. */
5638 if (! ST_REG_P (true_regnum (operands[0]))
5639 || ! FP_REG_P (true_regnum (operands[2])))
5640 abort ();
5641
5642 /* We need to get the source in SFmode so that the insn is
5643 recognized. */
5644 if (GET_CODE (operands[1]) == MEM)
5645 source = change_address (operands[1], SFmode, NULL_RTX);
5646 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
c5c76735 5647 source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
b8eb88d0
ILT
5648 else
5649 source = operands[1];
5650
c5c76735
JL
5651 fp1 = gen_rtx_REG (SFmode, REGNO (operands[2]));
5652 fp2 = gen_rtx_REG (SFmode, REGNO (operands[2]) + 1);
b8eb88d0
ILT
5653
5654 emit_insn (gen_move_insn (fp1, source));
c5c76735
JL
5655 emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
5656 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5657 gen_rtx_LT (CCmode, fp2, fp1)));
b8eb88d0
ILT
5658
5659 DONE;
5660}")
5661
5662(define_expand "reload_outcc"
5663 [(set (match_operand:CC 0 "general_operand" "=z")
5664 (match_operand:CC 1 "register_operand" "z"))
5665 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
76ee8042 5666 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5667 "
5668{
5669 /* This is called when we are copying a condition code register out
5670 to save it somewhere. Operand 0 should be the location we are
5671 going to save it to. Operand 1 should be the condition code
5672 register. Operand 2 should be a scratch general purpose register
5673 created for us by reload. The mips_secondary_reload_class
5674 function should have told reload that we don't need a scratch
5675 register if the destination is a general purpose register anyhow. */
5676 if (ST_REG_P (true_regnum (operands[0]))
5677 || GP_REG_P (true_regnum (operands[0]))
5678 || ! ST_REG_P (true_regnum (operands[1]))
5679 || ! GP_REG_P (true_regnum (operands[2])))
5680 abort ();
5681
5682 /* All we have to do is copy the value from the condition code to
5683 the data register, which movcc can handle, and then store the
5684 value into the real final destination. */
5685 emit_insn (gen_move_insn (operands[2], operands[1]));
5686 emit_insn (gen_move_insn (operands[0], operands[2]));
5687
5688 DONE;
5689}")
5690
5691;; MIPS4 supports loading and storing a floating point register from
5692;; the sum of two general registers. We use two versions for each of
5693;; these four instructions: one where the two general registers are
5694;; SImode, and one where they are DImode. This is because general
5695;; registers will be in SImode when they hold 32 bit values, but,
5696;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5697;; instructions will still work correctly.
5698
5699;; ??? Perhaps it would be better to support these instructions by
5700;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5701;; these instructions can only be used to load and store floating
5702;; point registers, that would probably cause trouble in reload.
5703
5704(define_insn ""
5705 [(set (match_operand:SF 0 "register_operand" "=f")
5706 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5707 (match_operand:SI 2 "register_operand" "d"))))]
1d5d552e 5708 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5709 "lwxc1\\t%0,%1(%2)"
5710 [(set_attr "type" "load")
0ff83799 5711 (set_attr "mode" "SF")])
b8eb88d0
ILT
5712
5713(define_insn ""
5714 [(set (match_operand:SF 0 "register_operand" "=f")
1908a152
ILT
5715 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5716 (match_operand:DI 2 "se_register_operand" "d"))))]
1d5d552e 5717 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5718 "lwxc1\\t%0,%1(%2)"
5719 [(set_attr "type" "load")
0ff83799 5720 (set_attr "mode" "SF")])
b8eb88d0
ILT
5721
5722(define_insn ""
5723 [(set (match_operand:DF 0 "register_operand" "=f")
5724 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5725 (match_operand:SI 2 "register_operand" "d"))))]
1d5d552e 5726 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5727 "ldxc1\\t%0,%1(%2)"
5728 [(set_attr "type" "load")
0ff83799 5729 (set_attr "mode" "DF")])
b8eb88d0
ILT
5730
5731(define_insn ""
5732 [(set (match_operand:DF 0 "register_operand" "=f")
1908a152
ILT
5733 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5734 (match_operand:DI 2 "se_register_operand" "d"))))]
1d5d552e 5735 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5736 "ldxc1\\t%0,%1(%2)"
5737 [(set_attr "type" "load")
0ff83799 5738 (set_attr "mode" "DF")])
b8eb88d0
ILT
5739
5740(define_insn ""
5741 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5742 (match_operand:SI 2 "register_operand" "d")))
c5c76735 5743 (match_operand:SF 0 "register_operand" "f"))]
1d5d552e 5744 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5745 "swxc1\\t%0,%1(%2)"
5746 [(set_attr "type" "store")
0ff83799 5747 (set_attr "mode" "SF")])
b8eb88d0
ILT
5748
5749(define_insn ""
1908a152
ILT
5750 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5751 (match_operand:DI 2 "se_register_operand" "d")))
c5c76735 5752 (match_operand:SF 0 "register_operand" "f"))]
1d5d552e 5753 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
b8eb88d0
ILT
5754 "swxc1\\t%0,%1(%2)"
5755 [(set_attr "type" "store")
0ff83799 5756 (set_attr "mode" "SF")])
b8eb88d0
ILT
5757
5758(define_insn ""
5759 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5760 (match_operand:SI 2 "register_operand" "d")))
c5c76735 5761 (match_operand:DF 0 "register_operand" "f"))]
1d5d552e 5762 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5763 "sdxc1\\t%0,%1(%2)"
5764 [(set_attr "type" "store")
0ff83799 5765 (set_attr "mode" "DF")])
b8eb88d0
ILT
5766
5767(define_insn ""
1908a152
ILT
5768 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5769 (match_operand:DI 2 "se_register_operand" "d")))
c5c76735 5770 (match_operand:DF 0 "register_operand" "f"))]
1d5d552e 5771 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
5772 "sdxc1\\t%0,%1(%2)"
5773 [(set_attr "type" "store")
0ff83799 5774 (set_attr "mode" "DF")])
b8eb88d0 5775
8ef30996
MM
5776;; 16-bit Integer moves
5777
5778;; Unlike most other insns, the move insns can't be split with
5779;; different predicates, because register spilling and other parts of
5780;; the compiler, have memoized the insn number already.
5781;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5782
0fb5ac6f
MM
5783(define_expand "movhi"
5784 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5785 (match_operand:HI 1 "general_operand" ""))]
8ef30996 5786 ""
ed50ab35
MM
5787 "
5788{
5789 if ((reload_in_progress | reload_completed) == 0
5790 && !register_operand (operands[0], HImode)
5791 && !register_operand (operands[1], HImode)
2bcb2ab3
GK
5792 && (TARGET_MIPS16
5793 || (GET_CODE (operands[1]) != CONST_INT
5794 || INTVAL (operands[1]) != 0)))
ed50ab35
MM
5795 {
5796 rtx temp = force_reg (HImode, operands[1]);
5797 emit_move_insn (operands[0], temp);
5798 DONE;
5799 }
5800}")
0fb5ac6f
MM
5801
5802;; The difference between these two is whether or not ints are allowed
5803;; in FP registers (off by default, use -mdebugh to enable).
5804
5805(define_insn "movhi_internal1"
252e25c6
MM
5806 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5807 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
2bcb2ab3 5808 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
ed50ab35
MM
5809 && (register_operand (operands[0], HImode)
5810 || register_operand (operands[1], HImode)
5811 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
8ef30996
MM
5812 "* return mips_move_1word (operands, insn, TRUE);"
5813 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
92b4cee1 5814 (set_attr "mode" "HI")
0ff83799 5815 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
8ef30996 5816
0fb5ac6f
MM
5817(define_insn "movhi_internal2"
5818 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5819 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
2bcb2ab3 5820 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
ed50ab35
MM
5821 && (register_operand (operands[0], HImode)
5822 || register_operand (operands[1], HImode)
5823 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
0fb5ac6f
MM
5824 "* return mips_move_1word (operands, insn, TRUE);"
5825 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5826 (set_attr "mode" "HI")
0ff83799 5827 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
0fb5ac6f 5828
2bcb2ab3
GK
5829(define_insn ""
5830 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5831 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5832 "TARGET_MIPS16
5833 && (register_operand (operands[0], HImode)
5834 || register_operand (operands[1], HImode))"
5835 "* return mips_move_1word (operands, insn, TRUE);"
5836 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5837 (set_attr "mode" "HI")
5838 (set_attr_alternative "length"
0ff83799
MM
5839 [(const_int 4)
5840 (const_int 4)
5841 (const_int 4)
2bcb2ab3 5842 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
5843 (const_int 4)
5844 (const_int 8))
2bcb2ab3 5845 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
5846 (const_int 8)
5847 (const_int 12))
5848 (const_int 4)
5849 (const_int 8)
5850 (const_int 4)
5851 (const_int 8)
5852 (const_int 4)])])
2bcb2ab3
GK
5853
5854
5855;; On the mips16, we can split lh $r,N($r) into an add and a load,
5856;; when the original load is a 4 byte instruction but the add and the
5857;; load are 2 2 byte instructions.
5858
5859(define_split
5860 [(set (match_operand:HI 0 "register_operand" "")
988ee12c 5861 (mem:HI (plus:SI (match_dup 0)
2bcb2ab3
GK
5862 (match_operand:SI 1 "const_int_operand" ""))))]
5863 "TARGET_MIPS16 && reload_completed
5864 && GET_CODE (operands[0]) == REG
5865 && M16_REG_P (REGNO (operands[0]))
5866 && GET_CODE (operands[1]) == CONST_INT
5867 && ((INTVAL (operands[1]) < 0
5868 && INTVAL (operands[1]) >= -0x80)
5869 || (INTVAL (operands[1]) >= 32 * 2
5870 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5871 || (INTVAL (operands[1]) >= 0
5872 && INTVAL (operands[1]) < 32 * 2
5873 && (INTVAL (operands[1]) & 1) != 0))"
5874 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5875 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5876 "
5877{
5878 HOST_WIDE_INT val = INTVAL (operands[1]);
5879
5880 if (val < 0)
5881 operands[2] = GEN_INT (0);
5882 else if (val >= 32 * 2)
5883 {
5884 int off = val & 1;
5885
5886 operands[1] = GEN_INT (0x7e + off);
5887 operands[2] = GEN_INT (val - off - 0x7e);
5888 }
5889 else
5890 {
5891 int off = val & 1;
5892
5893 operands[1] = GEN_INT (off);
5894 operands[2] = GEN_INT (val - off);
5895 }
5896}")
0fb5ac6f 5897
8ef30996
MM
5898;; 8-bit Integer moves
5899
5900;; Unlike most other insns, the move insns can't be split with
5901;; different predicates, because register spilling and other parts of
5902;; the compiler, have memoized the insn number already.
5903;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5904
0fb5ac6f
MM
5905(define_expand "movqi"
5906 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5907 (match_operand:QI 1 "general_operand" ""))]
8ef30996 5908 ""
ed50ab35
MM
5909 "
5910{
5911 if ((reload_in_progress | reload_completed) == 0
5912 && !register_operand (operands[0], QImode)
5913 && !register_operand (operands[1], QImode)
2bcb2ab3
GK
5914 && (TARGET_MIPS16
5915 || (GET_CODE (operands[1]) != CONST_INT
5916 || INTVAL (operands[1]) != 0)))
ed50ab35
MM
5917 {
5918 rtx temp = force_reg (QImode, operands[1]);
5919 emit_move_insn (operands[0], temp);
5920 DONE;
5921 }
5922}")
0fb5ac6f
MM
5923
5924;; The difference between these two is whether or not ints are allowed
5925;; in FP registers (off by default, use -mdebugh to enable).
5926
5927(define_insn "movqi_internal1"
252e25c6
MM
5928 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
5929 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
2bcb2ab3 5930 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
ed50ab35
MM
5931 && (register_operand (operands[0], QImode)
5932 || register_operand (operands[1], QImode)
5933 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
8ef30996
MM
5934 "* return mips_move_1word (operands, insn, TRUE);"
5935 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
92b4cee1 5936 (set_attr "mode" "QI")
0ff83799 5937 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
8ef30996 5938
0fb5ac6f
MM
5939(define_insn "movqi_internal2"
5940 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5941 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
2bcb2ab3 5942 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
ed50ab35
MM
5943 && (register_operand (operands[0], QImode)
5944 || register_operand (operands[1], QImode)
5945 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
0fb5ac6f
MM
5946 "* return mips_move_1word (operands, insn, TRUE);"
5947 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5948 (set_attr "mode" "QI")
0ff83799 5949 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
0fb5ac6f 5950
2bcb2ab3
GK
5951(define_insn ""
5952 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5953 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5954 "TARGET_MIPS16
5955 && (register_operand (operands[0], QImode)
5956 || register_operand (operands[1], QImode))"
5957 "* return mips_move_1word (operands, insn, TRUE);"
5958 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5959 (set_attr "mode" "QI")
5960 (set_attr_alternative "length"
0ff83799
MM
5961 [(const_int 4)
5962 (const_int 4)
5963 (const_int 4)
2bcb2ab3 5964 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
0ff83799
MM
5965 (const_int 4)
5966 (const_int 8))
2bcb2ab3 5967 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
0ff83799
MM
5968 (const_int 8)
5969 (const_int 12))
5970 (const_int 4)
5971 (const_int 8)
5972 (const_int 4)
5973 (const_int 8)
5974 (const_int 4)])])
2bcb2ab3
GK
5975
5976
5977;; On the mips16, we can split lb $r,N($r) into an add and a load,
5978;; when the original load is a 4 byte instruction but the add and the
5979;; load are 2 2 byte instructions.
5980
5981(define_split
5982 [(set (match_operand:QI 0 "register_operand" "")
5983 (mem:QI (plus:SI (match_dup 0)
5984 (match_operand:SI 1 "const_int_operand" ""))))]
5985 "TARGET_MIPS16 && reload_completed
5986 && GET_CODE (operands[0]) == REG
5987 && M16_REG_P (REGNO (operands[0]))
5988 && GET_CODE (operands[1]) == CONST_INT
5989 && ((INTVAL (operands[1]) < 0
5990 && INTVAL (operands[1]) >= -0x80)
5991 || (INTVAL (operands[1]) >= 32
5992 && INTVAL (operands[1]) <= 31 + 0x7f))"
5993 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5994 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5995 "
5996{
5997 HOST_WIDE_INT val = INTVAL (operands[1]);
5998
5999 if (val < 0)
6000 operands[2] = GEN_INT (0);
6001 else
6002 {
6003 operands[1] = GEN_INT (0x7f);
6004 operands[2] = GEN_INT (val - 0x7f);
6005 }
6006}")
8ef30996
MM
6007
6008;; 32-bit floating point moves
6009
ed50ab35
MM
6010(define_expand "movsf"
6011 [(set (match_operand:SF 0 "nonimmediate_operand" "")
6012 (match_operand:SF 1 "general_operand" ""))]
6013 ""
6014 "
6015{
6016 if ((reload_in_progress | reload_completed) == 0
6017 && !register_operand (operands[0], SFmode)
6018 && !register_operand (operands[1], SFmode)
2bcb2ab3 6019 && (TARGET_MIPS16
6e92f4b6
KG
6020 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6021 && operands[1] != CONST0_RTX (SFmode))))
ed50ab35
MM
6022 {
6023 rtx temp = force_reg (SFmode, operands[1]);
6024 emit_move_insn (operands[0], temp);
6025 DONE;
6026 }
6027}")
6028
b0193a92 6029(define_insn "movsf_internal1"
8ef30996 6030 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
bb621ad7 6031 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
b0193a92
MM
6032 "TARGET_HARD_FLOAT
6033 && (register_operand (operands[0], SFmode)
6034 || register_operand (operands[1], SFmode)
6035 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6036 || operands[1] == CONST0_RTX (SFmode))"
8ef30996
MM
6037 "* return mips_move_1word (operands, insn, FALSE);"
6038 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
92b4cee1 6039 (set_attr "mode" "SF")
0ff83799 6040 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
8ef30996 6041
ed50ab35 6042
b0193a92
MM
6043(define_insn "movsf_internal2"
6044 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
bb621ad7 6045 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
2bcb2ab3 6046 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
b0193a92
MM
6047 && (register_operand (operands[0], SFmode)
6048 || register_operand (operands[1], SFmode)
6049 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6050 || operands[1] == CONST0_RTX (SFmode))"
6051 "* return mips_move_1word (operands, insn, FALSE);"
6052 [(set_attr "type" "move,load,load,store,store")
6053 (set_attr "mode" "SF")
0ff83799 6054 (set_attr "length" "4,4,8,4,8")])
b0193a92 6055
2bcb2ab3
GK
6056(define_insn ""
6057 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6058 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
6059 "TARGET_MIPS16
6060 && (register_operand (operands[0], SFmode)
6061 || register_operand (operands[1], SFmode))"
6062 "* return mips_move_1word (operands, insn, FALSE);"
6063 [(set_attr "type" "move,move,move,load,load,store,store")
6064 (set_attr "mode" "SF")
0ff83799 6065 (set_attr "length" "4,4,4,4,8,4,8")])
2bcb2ab3 6066
b0193a92 6067
8ef30996
MM
6068;; 64-bit floating point moves
6069
ed50ab35
MM
6070(define_expand "movdf"
6071 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6072 (match_operand:DF 1 "general_operand" ""))]
6073 ""
6074 "
6075{
6076 if ((reload_in_progress | reload_completed) == 0
6077 && !register_operand (operands[0], DFmode)
6078 && !register_operand (operands[1], DFmode)
2bcb2ab3 6079 && (TARGET_MIPS16
6e92f4b6
KG
6080 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6081 && operands[1] != CONST0_RTX (DFmode))))
ed50ab35
MM
6082 {
6083 rtx temp = force_reg (DFmode, operands[1]);
6084 emit_move_insn (operands[0], temp);
6085 DONE;
6086 }
6087}")
6088
b0193a92 6089(define_insn "movdf_internal1"
2bcb2ab3
GK
6090 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6091 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
64d8baf9 6092 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
46299de9 6093 && TARGET_DOUBLE_FLOAT
b0193a92
MM
6094 && (register_operand (operands[0], DFmode)
6095 || register_operand (operands[1], DFmode)
6096 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6097 || operands[1] == CONST0_RTX (DFmode))"
8ef30996
MM
6098 "* return mips_move_2words (operands, insn); "
6099 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
92b4cee1 6100 (set_attr "mode" "DF")
0ff83799 6101 (set_attr "length" "4,8,16,8,16,16,8,8,8,8,16,8,16")])
8ef30996 6102
64d8baf9 6103(define_insn "movdf_internal1a"
fc5b7cda
AH
6104 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*d,*To,*R,*d")
6105 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,*F,*To,*R,*d,*d,*d"))]
64d8baf9 6106 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
46299de9 6107 && TARGET_DOUBLE_FLOAT
64d8baf9 6108 && (register_operand (operands[0], DFmode)
89a5e42b 6109 || register_operand (operands[1], DFmode)
64d8baf9
JW
6110 || (GET_CODE (operands [0]) == MEM
6111 && ((GET_CODE (operands[1]) == CONST_INT
6112 && INTVAL (operands[1]) == 0)
89a5e42b 6113 || operands[1] == CONST0_RTX (DFmode))))"
64d8baf9 6114 "* return mips_move_2words (operands, insn); "
fc5b7cda 6115 [(set_attr "type" "move,load,store,store,store,store,load,load,load,store,store,move")
64d8baf9 6116 (set_attr "mode" "DF")
fc5b7cda 6117 (set_attr "length" "4,8,4,4,8,8,8,8,4,8,4,4")])
64d8baf9 6118
b0193a92 6119(define_insn "movdf_internal2"
2bcb2ab3
GK
6120 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To")
6121 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d"))]
6122 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
b0193a92
MM
6123 && (register_operand (operands[0], DFmode)
6124 || register_operand (operands[1], DFmode)
6125 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6126 || operands[1] == CONST0_RTX (DFmode))"
6127 "* return mips_move_2words (operands, insn); "
6128 [(set_attr "type" "move,load,load,store,store")
6129 (set_attr "mode" "DF")
0ff83799 6130 (set_attr "length" "8,8,16,8,16")])
b0193a92 6131
2bcb2ab3
GK
6132(define_insn ""
6133 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6134 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6135 "TARGET_MIPS16
6136 && (register_operand (operands[0], DFmode)
6137 || register_operand (operands[1], DFmode))"
6138 "* return mips_move_2words (operands, insn);"
6139 [(set_attr "type" "move,move,move,load,load,store,store")
6140 (set_attr "mode" "DF")
0ff83799 6141 (set_attr "length" "8,8,8,8,16,8,16")])
2bcb2ab3 6142
8ef30996
MM
6143(define_split
6144 [(set (match_operand:DF 0 "register_operand" "")
6145 (match_operand:DF 1 "register_operand" ""))]
2c14c928 6146 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
6147 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6148 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
8ef30996 6149 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
ddef6bc7 6150 (set (subreg:SI (match_dup 0) 4) (subreg:SI (match_dup 1) 4))]
8ef30996
MM
6151 "")
6152
e19ff60f
JW
6153;; Instructions to load the global pointer register.
6154;; This is volatile to make sure that the scheduler won't move any symbol_ref
6155;; uses in front of it. All symbol_refs implicitly use the gp reg.
6156
6157(define_insn "loadgp"
6158 [(set (reg:DI 28)
e5e809f4
JL
6159 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6160 (match_operand:DI 1 "register_operand" "")] 2))
e19ff60f
JW
6161 (clobber (reg:DI 1))]
6162 ""
e5e809f4 6163 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
e19ff60f
JW
6164 [(set_attr "type" "move")
6165 (set_attr "mode" "DI")
0ff83799 6166 (set_attr "length" "12")])
26b8e6e5 6167\f
8ef30996
MM
6168;; Block moves, see mips.c for more details.
6169;; Argument 0 is the destination
6170;; Argument 1 is the source
6171;; Argument 2 is the length
6172;; Argument 3 is the alignment
6173
6174(define_expand "movstrsi"
e9a25f70
JL
6175 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6176 (match_operand:BLK 1 "general_operand" ""))
8ef30996
MM
6177 (use (match_operand:SI 2 "arith32_operand" ""))
6178 (use (match_operand:SI 3 "immediate_operand" ""))])]
2bcb2ab3 6179 "!TARGET_MIPS16"
8ef30996
MM
6180 "
6181{
6182 if (operands[0]) /* avoid unused code messages */
6183 {
6184 expand_block_move (operands);
6185 DONE;
6186 }
6187}")
6188
842eb20e
MM
6189;; Insn generated by block moves
6190
6191(define_insn "movstrsi_internal"
aa4e54c4
JW
6192 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6193 (match_operand:BLK 1 "memory_operand" "o")) ;; source
26b8e6e5
MM
6194 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6195 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6196 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6197 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6198 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6199 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6200 (use (const_int 0))] ;; normal block move
6201 ""
6202 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
e9a25f70 6203 [(set_attr "type" "store")
842eb20e 6204 (set_attr "mode" "none")
0ff83799 6205 (set_attr "length" "80")])
842eb20e 6206
2bcb2ab3
GK
6207;; We need mips16 versions, because an offset from the stack pointer
6208;; is not offsettable, since the stack pointer can only handle 4 and 8
6209;; byte loads.
6210
2bcb2ab3
GK
6211(define_insn ""
6212 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
cf45bb06 6213 (match_operand:BLK 1 "memory_operand" "o")) ;; source
2bcb2ab3
GK
6214 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6215 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6216 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6217 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6218 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6219 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6220 (use (const_int 0))] ;; normal block move
6221 "TARGET_MIPS16"
6222 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6223 [(set_attr "type" "multi")
6224 (set_attr "mode" "none")
0ff83799 6225 (set_attr "length" "80")])
2bcb2ab3 6226
26b8e6e5
MM
6227;; Split a block move into 2 parts, the first part is everything
6228;; except for the last move, and the second part is just the last
6229;; store, which is exactly 1 instruction (ie, not a usw), so it can
6230;; fill a delay slot. This also prevents a bug in delayed branches
6231;; from showing up, which reuses one of the registers in our clobbers.
6232
6233(define_split
6234 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6235 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6236 (clobber (match_operand:SI 4 "register_operand" ""))
6237 (clobber (match_operand:SI 5 "register_operand" ""))
6238 (clobber (match_operand:SI 6 "register_operand" ""))
6239 (clobber (match_operand:SI 7 "register_operand" ""))
6240 (use (match_operand:SI 2 "small_int" ""))
6241 (use (match_operand:SI 3 "small_int" ""))
6242 (use (const_int 0))]
6243
6244 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6245
6246 ;; All but the last move
6247 [(parallel [(set (mem:BLK (match_dup 0))
6248 (mem:BLK (match_dup 1)))
6249 (clobber (match_dup 4))
6250 (clobber (match_dup 5))
6251 (clobber (match_dup 6))
6252 (clobber (match_dup 7))
6253 (use (match_dup 2))
6254 (use (match_dup 3))
6255 (use (const_int 1))])
6256
6257 ;; The last store, so it can fill a delay slot
6258 (parallel [(set (mem:BLK (match_dup 0))
6259 (mem:BLK (match_dup 1)))
6260 (clobber (match_dup 4))
6261 (clobber (match_dup 5))
6262 (clobber (match_dup 6))
6263 (clobber (match_dup 7))
6264 (use (match_dup 2))
6265 (use (match_dup 3))
6266 (use (const_int 2))])]
6267
6268 "")
6269
6270(define_insn "movstrsi_internal2"
aa4e54c4
JW
6271 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6272 (match_operand:BLK 1 "memory_operand" "o")) ;; source
26b8e6e5
MM
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 1))] ;; all but last store
6280 ""
6281 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
e9a25f70 6282 [(set_attr "type" "store")
26b8e6e5 6283 (set_attr "mode" "none")
0ff83799 6284 (set_attr "length" "80")])
26b8e6e5 6285
2bcb2ab3 6286(define_insn ""
cf45bb06
RH
6287 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6288 (match_operand:BLK 1 "memory_operand" "o")) ;; source
2bcb2ab3
GK
6289 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6290 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6291 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6292 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6293 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6294 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6295 (use (const_int 1))] ;; all but last store
6296 "TARGET_MIPS16"
6297 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6298 [(set_attr "type" "multi")
6299 (set_attr "mode" "none")
0ff83799 6300 (set_attr "length" "80")])
2bcb2ab3 6301
26b8e6e5
MM
6302(define_insn "movstrsi_internal3"
6303 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
6304 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
6305 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6306 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6307 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6308 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6309 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6310 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
bb621ad7 6311 (use (const_int 2))] ;; just last store of block move
26b8e6e5
MM
6312 ""
6313 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6314 [(set_attr "type" "store")
0ff83799 6315 (set_attr "mode" "none")])
8ef30996
MM
6316\f
6317;;
6318;; ....................
6319;;
6320;; SHIFTS
6321;;
6322;; ....................
6323
2bcb2ab3
GK
6324;; Many of these instructions uses trivial define_expands, because we
6325;; want to use a different set of constraints when TARGET_MIPS16.
6326
6327(define_expand "ashlsi3"
8ef30996
MM
6328 [(set (match_operand:SI 0 "register_operand" "=d")
6329 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6330 (match_operand:SI 2 "arith_operand" "dI")))]
6331 ""
2bcb2ab3
GK
6332 "
6333{
6334 /* On the mips16, a shift of more than 8 is a four byte instruction,
6335 so, for a shift between 8 and 16, it is just as fast to do two
6336 shifts of 8 or less. If there is a lot of shifting going on, we
6337 may win in CSE. Otherwise combine will put the shifts back
6338 together again. This can be called by function_arg, so we must
6339 be careful not to allocate a new register if we've reached the
6340 reload pass. */
6341 if (TARGET_MIPS16
6342 && optimize
6343 && GET_CODE (operands[2]) == CONST_INT
6344 && INTVAL (operands[2]) > 8
6345 && INTVAL (operands[2]) <= 16
6346 && ! reload_in_progress
6347 && ! reload_completed)
6348 {
6349 rtx temp = gen_reg_rtx (SImode);
6350
6351 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6352 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6353 GEN_INT (INTVAL (operands[2]) - 8)));
6354 DONE;
6355 }
6356}")
6357
6358(define_insn "ashlsi3_internal1"
6359 [(set (match_operand:SI 0 "register_operand" "=d")
6360 (ashift:SI (match_operand:SI 1 "register_operand" "d")
6361 (match_operand:SI 2 "arith_operand" "dI")))]
6362 "!TARGET_MIPS16"
8ef30996
MM
6363 "*
6364{
6365 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 6366 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6367
6368 return \"sll\\t%0,%1,%2\";
6369}"
6370 [(set_attr "type" "arith")
0ff83799 6371 (set_attr "mode" "SI")])
8ef30996 6372
2bcb2ab3
GK
6373(define_insn "ashlsi3_internal2"
6374 [(set (match_operand:SI 0 "register_operand" "=d,d")
6375 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6376 (match_operand:SI 2 "arith_operand" "d,I")))]
6377 "TARGET_MIPS16"
6378 "*
6379{
6380 if (which_alternative == 0)
6381 return \"sll\\t%0,%2\";
6382
6383 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 6384 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2bcb2ab3
GK
6385
6386 return \"sll\\t%0,%1,%2\";
6387}"
6388 [(set_attr "type" "arith")
6389 (set_attr "mode" "SI")
6390 (set_attr_alternative "length"
0ff83799 6391 [(const_int 4)
2bcb2ab3 6392 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
6393 (const_int 4)
6394 (const_int 8))])])
2bcb2ab3
GK
6395
6396;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6397
6398(define_split
6399 [(set (match_operand:SI 0 "register_operand" "")
6400 (ashift:SI (match_operand:SI 1 "register_operand" "")
6401 (match_operand:SI 2 "const_int_operand" "")))]
6402 "TARGET_MIPS16
6403 && reload_completed
6404 && GET_CODE (operands[2]) == CONST_INT
6405 && INTVAL (operands[2]) > 8
6406 && INTVAL (operands[2]) <= 16"
6407 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6408 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6409"
6410{
6411 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6412}")
8ef30996
MM
6413
6414(define_expand "ashldi3"
6415 [(parallel [(set (match_operand:DI 0 "register_operand" "")
1908a152 6416 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
8ef30996
MM
6417 (match_operand:SI 2 "arith_operand" "")))
6418 (clobber (match_dup 3))])]
2bcb2ab3 6419 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
6420 "
6421{
6422 if (TARGET_64BIT)
6423 {
2bcb2ab3
GK
6424 /* On the mips16, a shift of more than 8 is a four byte
6425 instruction, so, for a shift between 8 and 16, it is just as
6426 fast to do two shifts of 8 or less. If there is a lot of
6427 shifting going on, we may win in CSE. Otherwise combine will
6428 put the shifts back together again. This can be called by
6429 function_arg, so we must be careful not to allocate a new
6430 register if we've reached the reload pass. */
6431 if (TARGET_MIPS16
6432 && optimize
6433 && GET_CODE (operands[2]) == CONST_INT
6434 && INTVAL (operands[2]) > 8
6435 && INTVAL (operands[2]) <= 16
6436 && ! reload_in_progress
6437 && ! reload_completed)
6438 {
6439 rtx temp = gen_reg_rtx (DImode);
6440
6441 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6442 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6443 GEN_INT (INTVAL (operands[2]) - 8)));
6444 DONE;
6445 }
6446
bb621ad7
JW
6447 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6448 operands[2]));
6449 DONE;
6450 }
6451
6452 operands[3] = gen_reg_rtx (SImode);
6453}")
8ef30996
MM
6454
6455
6456(define_insn "ashldi3_internal"
0fb5ac6f 6457 [(set (match_operand:DI 0 "register_operand" "=&d")
8ef30996
MM
6458 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6459 (match_operand:SI 2 "register_operand" "d")))
6460 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6461 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
6462 "*
6463{
6464 operands[4] = const0_rtx;
6465 dslots_jump_total += 3;
6466 dslots_jump_filled += 2;
6467
6468 return \"sll\\t%3,%2,26\\n\\
6469\\tbgez\\t%3,1f\\n\\
6470\\tsll\\t%M0,%L1,%2\\n\\
6471\\t%(b\\t3f\\n\\
6472\\tmove\\t%L0,%z4%)\\n\\
6473\\n\\
efa3896a 6474%~1:\\n\\
8ef30996
MM
6475\\t%(beq\\t%3,%z4,2f\\n\\
6476\\tsll\\t%M0,%M1,%2%)\\n\\
6477\\n\\
6478\\tsubu\\t%3,%z4,%2\\n\\
6479\\tsrl\\t%3,%L1,%3\\n\\
6480\\tor\\t%M0,%M0,%3\\n\\
efa3896a 6481%~2:\\n\\
8ef30996 6482\\tsll\\t%L0,%L1,%2\\n\\
efa3896a 6483%~3:\";
8ef30996
MM
6484}"
6485 [(set_attr "type" "darith")
6486 (set_attr "mode" "SI")
0ff83799 6487 (set_attr "length" "48")])
8ef30996
MM
6488
6489
6490(define_insn "ashldi3_internal2"
6491 [(set (match_operand:DI 0 "register_operand" "=d")
6492 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6493 (match_operand:SI 2 "small_int" "IJK")))
6494 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3
GK
6495 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6496 && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
6497 "*
6498{
95936d18 6499 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6500 operands[4] = const0_rtx;
6501 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6502}"
6503 [(set_attr "type" "darith")
6504 (set_attr "mode" "DI")
0ff83799 6505 (set_attr "length" "8")])
8ef30996
MM
6506
6507
6508(define_split
6509 [(set (match_operand:DI 0 "register_operand" "")
6510 (ashift:DI (match_operand:DI 1 "register_operand" "")
6511 (match_operand:SI 2 "small_int" "")))
6512 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6513 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6514 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6515 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6516 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6517 && (INTVAL (operands[2]) & 32) != 0"
6518
ddef6bc7 6519 [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
8ef30996
MM
6520 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6521
95936d18 6522 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6523
6524
6525(define_split
6526 [(set (match_operand:DI 0 "register_operand" "")
6527 (ashift:DI (match_operand:DI 1 "register_operand" "")
6528 (match_operand:SI 2 "small_int" "")))
6529 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6530 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6531 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6532 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6533 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6534 && (INTVAL (operands[2]) & 32) != 0"
6535
ddef6bc7
JJ
6536 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6537 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
8ef30996 6538
95936d18 6539 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6540
6541
6542(define_insn "ashldi3_internal3"
6543 [(set (match_operand:DI 0 "register_operand" "=d")
6544 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6545 (match_operand:SI 2 "small_int" "IJK")))
6546 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6547 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6548 && (INTVAL (operands[2]) & 63) < 32
6549 && (INTVAL (operands[2]) & 63) != 0"
6550 "*
6551{
6552 int amount = INTVAL (operands[2]);
6553
c5c76735 6554 operands[2] = GEN_INT (amount & 31);
8ef30996 6555 operands[4] = const0_rtx;
c5c76735 6556 operands[5] = GEN_INT ((-amount) & 31);
8ef30996
MM
6557
6558 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6559}"
6560 [(set_attr "type" "darith")
6561 (set_attr "mode" "DI")
0ff83799 6562 (set_attr "length" "16")])
8ef30996
MM
6563
6564
6565(define_split
6566 [(set (match_operand:DI 0 "register_operand" "")
6567 (ashift:DI (match_operand:DI 1 "register_operand" "")
6568 (match_operand:SI 2 "small_int" "")))
6569 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6570 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6571 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6572 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6573 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6574 && (INTVAL (operands[2]) & 63) < 32
6575 && (INTVAL (operands[2]) & 63) != 0"
6576
ddef6bc7
JJ
6577 [(set (subreg:SI (match_dup 0) 4)
6578 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6579 (match_dup 2)))
6580
6581 (set (match_dup 3)
6582 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6583 (match_dup 4)))
6584
ddef6bc7
JJ
6585 (set (subreg:SI (match_dup 0) 4)
6586 (ior:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
6587 (match_dup 3)))
6588
6589 (set (subreg:SI (match_dup 0) 0)
6590 (ashift:SI (subreg:SI (match_dup 1) 0)
6591 (match_dup 2)))]
6592 "
6593{
6594 int amount = INTVAL (operands[2]);
c5c76735
JL
6595 operands[2] = GEN_INT (amount & 31);
6596 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6597}")
6598
6599
6600(define_split
6601 [(set (match_operand:DI 0 "register_operand" "")
6602 (ashift:DI (match_operand:DI 1 "register_operand" "")
6603 (match_operand:SI 2 "small_int" "")))
6604 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6605 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6606 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6607 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6608 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6609 && (INTVAL (operands[2]) & 63) < 32
6610 && (INTVAL (operands[2]) & 63) != 0"
6611
6612 [(set (subreg:SI (match_dup 0) 0)
6613 (ashift:SI (subreg:SI (match_dup 1) 0)
6614 (match_dup 2)))
6615
6616 (set (match_dup 3)
ddef6bc7 6617 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6618 (match_dup 4)))
6619
6620 (set (subreg:SI (match_dup 0) 0)
6621 (ior:SI (subreg:SI (match_dup 0) 0)
6622 (match_dup 3)))
6623
ddef6bc7
JJ
6624 (set (subreg:SI (match_dup 0) 4)
6625 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6626 (match_dup 2)))]
6627 "
6628{
6629 int amount = INTVAL (operands[2]);
c5c76735
JL
6630 operands[2] = GEN_INT (amount & 31);
6631 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6632}")
6633
6634
bb621ad7
JW
6635(define_insn "ashldi3_internal4"
6636 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 6637 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 6638 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 6639 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
6640 "*
6641{
6642 if (GET_CODE (operands[2]) == CONST_INT)
6643 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6644
6645 return \"dsll\\t%0,%1,%2\";
6646}"
6647 [(set_attr "type" "arith")
0ff83799 6648 (set_attr "mode" "DI")])
bb621ad7 6649
2bcb2ab3
GK
6650(define_insn ""
6651 [(set (match_operand:DI 0 "register_operand" "=d,d")
6652 (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6653 (match_operand:SI 2 "arith_operand" "d,I")))]
6654 "TARGET_64BIT && TARGET_MIPS16"
6655 "*
6656{
6657 if (which_alternative == 0)
6658 return \"dsll\\t%0,%2\";
6659
6660 if (GET_CODE (operands[2]) == CONST_INT)
6661 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6662
6663 return \"dsll\\t%0,%1,%2\";
6664}"
6665 [(set_attr "type" "arith")
6666 (set_attr "mode" "DI")
6667 (set_attr_alternative "length"
0ff83799 6668 [(const_int 4)
2bcb2ab3 6669 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
6670 (const_int 4)
6671 (const_int 8))])])
2bcb2ab3 6672
bb621ad7 6673
2bcb2ab3
GK
6674;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6675
6676(define_split
6677 [(set (match_operand:DI 0 "register_operand" "")
6678 (ashift:DI (match_operand:DI 1 "register_operand" "")
6679 (match_operand:SI 2 "const_int_operand" "")))]
6680 "TARGET_MIPS16 && TARGET_64BIT
6681 && reload_completed
6682 && GET_CODE (operands[2]) == CONST_INT
6683 && INTVAL (operands[2]) > 8
6684 && INTVAL (operands[2]) <= 16"
6685 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6686 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6687"
6688{
6689 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6690}")
6691
6692(define_expand "ashrsi3"
8ef30996
MM
6693 [(set (match_operand:SI 0 "register_operand" "=d")
6694 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6695 (match_operand:SI 2 "arith_operand" "dI")))]
6696 ""
2bcb2ab3
GK
6697 "
6698{
6699 /* On the mips16, a shift of more than 8 is a four byte instruction,
6700 so, for a shift between 8 and 16, it is just as fast to do two
6701 shifts of 8 or less. If there is a lot of shifting going on, we
6702 may win in CSE. Otherwise combine will put the shifts back
6703 together again. */
6704 if (TARGET_MIPS16
6705 && optimize
6706 && GET_CODE (operands[2]) == CONST_INT
6707 && INTVAL (operands[2]) > 8
6708 && INTVAL (operands[2]) <= 16)
6709 {
6710 rtx temp = gen_reg_rtx (SImode);
6711
6712 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6713 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6714 GEN_INT (INTVAL (operands[2]) - 8)));
6715 DONE;
6716 }
6717}")
6718
6719(define_insn "ashrsi3_internal1"
6720 [(set (match_operand:SI 0 "register_operand" "=d")
6721 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6722 (match_operand:SI 2 "arith_operand" "dI")))]
6723 "!TARGET_MIPS16"
8ef30996
MM
6724 "*
6725{
6726 if (GET_CODE (operands[2]) == CONST_INT)
2bcb2ab3 6727 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6728
6729 return \"sra\\t%0,%1,%2\";
6730}"
6731 [(set_attr "type" "arith")
0ff83799 6732 (set_attr "mode" "SI")])
8ef30996 6733
2bcb2ab3
GK
6734(define_insn "ashrsi3_internal2"
6735 [(set (match_operand:SI 0 "register_operand" "=d,d")
6736 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6737 (match_operand:SI 2 "arith_operand" "d,I")))]
6738 "TARGET_MIPS16"
6739 "*
6740{
6741 if (which_alternative == 0)
6742 return \"sra\\t%0,%2\";
6743
6744 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 6745 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2bcb2ab3
GK
6746
6747 return \"sra\\t%0,%1,%2\";
6748}"
6749 [(set_attr "type" "arith")
6750 (set_attr "mode" "SI")
6751 (set_attr_alternative "length"
0ff83799 6752 [(const_int 4)
2bcb2ab3 6753 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
6754 (const_int 4)
6755 (const_int 8))])])
2bcb2ab3
GK
6756
6757
6758;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6759
6760(define_split
6761 [(set (match_operand:SI 0 "register_operand" "")
6762 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6763 (match_operand:SI 2 "const_int_operand" "")))]
6764 "TARGET_MIPS16
6765 && reload_completed
6766 && GET_CODE (operands[2]) == CONST_INT
6767 && INTVAL (operands[2]) > 8
6768 && INTVAL (operands[2]) <= 16"
6769 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6770 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6771"
6772{
6773 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6774}")
8ef30996
MM
6775
6776(define_expand "ashrdi3"
6777 [(parallel [(set (match_operand:DI 0 "register_operand" "")
1908a152 6778 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
8ef30996
MM
6779 (match_operand:SI 2 "arith_operand" "")))
6780 (clobber (match_dup 3))])]
2bcb2ab3 6781 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
6782 "
6783{
6784 if (TARGET_64BIT)
6785 {
2bcb2ab3
GK
6786 /* On the mips16, a shift of more than 8 is a four byte
6787 instruction, so, for a shift between 8 and 16, it is just as
6788 fast to do two shifts of 8 or less. If there is a lot of
6789 shifting going on, we may win in CSE. Otherwise combine will
6790 put the shifts back together again. */
6791 if (TARGET_MIPS16
6792 && optimize
6793 && GET_CODE (operands[2]) == CONST_INT
6794 && INTVAL (operands[2]) > 8
6795 && INTVAL (operands[2]) <= 16)
6796 {
6797 rtx temp = gen_reg_rtx (DImode);
6798
6799 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6800 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6801 GEN_INT (INTVAL (operands[2]) - 8)));
6802 DONE;
6803 }
6804
bb621ad7
JW
6805 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6806 operands[2]));
6807 DONE;
6808 }
6809
6810 operands[3] = gen_reg_rtx (SImode);
6811}")
8ef30996
MM
6812
6813
6814(define_insn "ashrdi3_internal"
0fb5ac6f 6815 [(set (match_operand:DI 0 "register_operand" "=&d")
8ef30996
MM
6816 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6817 (match_operand:SI 2 "register_operand" "d")))
6818 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6819 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
6820 "*
6821{
6822 operands[4] = const0_rtx;
6823 dslots_jump_total += 3;
6824 dslots_jump_filled += 2;
6825
6826 return \"sll\\t%3,%2,26\\n\\
6827\\tbgez\\t%3,1f\\n\\
6828\\tsra\\t%L0,%M1,%2\\n\\
6829\\t%(b\\t3f\\n\\
6830\\tsra\\t%M0,%M1,31%)\\n\\
6831\\n\\
efa3896a 6832%~1:\\n\\
8ef30996
MM
6833\\t%(beq\\t%3,%z4,2f\\n\\
6834\\tsrl\\t%L0,%L1,%2%)\\n\\
6835\\n\\
6836\\tsubu\\t%3,%z4,%2\\n\\
6837\\tsll\\t%3,%M1,%3\\n\\
6838\\tor\\t%L0,%L0,%3\\n\\
efa3896a 6839%~2:\\n\\
8ef30996 6840\\tsra\\t%M0,%M1,%2\\n\\
efa3896a 6841%~3:\";
8ef30996
MM
6842}"
6843 [(set_attr "type" "darith")
6844 (set_attr "mode" "DI")
0ff83799 6845 (set_attr "length" "48")])
8ef30996
MM
6846
6847
6848(define_insn "ashrdi3_internal2"
6849 [(set (match_operand:DI 0 "register_operand" "=d")
6850 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6851 (match_operand:SI 2 "small_int" "IJK")))
6852 (clobber (match_operand:SI 3 "register_operand" "=d"))]
bb621ad7 6853 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
6854 "*
6855{
95936d18 6856 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
6857 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6858}"
6859 [(set_attr "type" "darith")
6860 (set_attr "mode" "DI")
0ff83799 6861 (set_attr "length" "8")])
8ef30996
MM
6862
6863
6864(define_split
6865 [(set (match_operand:DI 0 "register_operand" "")
6866 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6867 (match_operand:SI 2 "small_int" "")))
6868 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 6869 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
6870 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6871 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6872 && (INTVAL (operands[2]) & 32) != 0"
6873
ddef6bc7
JJ
6874 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
6875 (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
8ef30996 6876
95936d18 6877 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6878
6879
6880(define_split
6881 [(set (match_operand:DI 0 "register_operand" "")
6882 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6883 (match_operand:SI 2 "small_int" "")))
6884 (clobber (match_operand:SI 3 "register_operand" ""))]
bb621ad7 6885 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
8ef30996
MM
6886 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6887 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6888 && (INTVAL (operands[2]) & 32) != 0"
6889
ddef6bc7 6890 [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
8ef30996
MM
6891 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6892
95936d18 6893 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
6894
6895
6896(define_insn "ashrdi3_internal3"
6897 [(set (match_operand:DI 0 "register_operand" "=d")
6898 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6899 (match_operand:SI 2 "small_int" "IJK")))
6900 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 6901 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6902 && (INTVAL (operands[2]) & 63) < 32
6903 && (INTVAL (operands[2]) & 63) != 0"
6904 "*
6905{
6906 int amount = INTVAL (operands[2]);
6907
c5c76735
JL
6908 operands[2] = GEN_INT (amount & 31);
6909 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6910
6911 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
6912}"
6913 [(set_attr "type" "darith")
6914 (set_attr "mode" "DI")
0ff83799 6915 (set_attr "length" "16")])
8ef30996
MM
6916
6917
6918(define_split
6919 [(set (match_operand:DI 0 "register_operand" "")
6920 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6921 (match_operand:SI 2 "small_int" "")))
6922 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6923 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6924 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6925 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6926 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6927 && (INTVAL (operands[2]) & 63) < 32
6928 && (INTVAL (operands[2]) & 63) != 0"
6929
6930 [(set (subreg:SI (match_dup 0) 0)
6931 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6932 (match_dup 2)))
6933
6934 (set (match_dup 3)
ddef6bc7 6935 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6936 (match_dup 4)))
6937
6938 (set (subreg:SI (match_dup 0) 0)
6939 (ior:SI (subreg:SI (match_dup 0) 0)
6940 (match_dup 3)))
6941
ddef6bc7
JJ
6942 (set (subreg:SI (match_dup 0) 4)
6943 (ashiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6944 (match_dup 2)))]
6945 "
6946{
6947 int amount = INTVAL (operands[2]);
c5c76735
JL
6948 operands[2] = GEN_INT (amount & 31);
6949 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6950}")
6951
6952
6953(define_split
6954 [(set (match_operand:DI 0 "register_operand" "")
6955 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6956 (match_operand:SI 2 "small_int" "")))
6957 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
6958 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6959 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
6960 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6961 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6962 && (INTVAL (operands[2]) & 63) < 32
6963 && (INTVAL (operands[2]) & 63) != 0"
6964
ddef6bc7
JJ
6965 [(set (subreg:SI (match_dup 0) 4)
6966 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
6967 (match_dup 2)))
6968
6969 (set (match_dup 3)
6970 (ashift:SI (subreg:SI (match_dup 1) 0)
6971 (match_dup 4)))
6972
ddef6bc7
JJ
6973 (set (subreg:SI (match_dup 0) 4)
6974 (ior:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
6975 (match_dup 3)))
6976
6977 (set (subreg:SI (match_dup 0) 0)
6978 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
6979 (match_dup 2)))]
6980 "
6981{
6982 int amount = INTVAL (operands[2]);
c5c76735
JL
6983 operands[2] = GEN_INT (amount & 31);
6984 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
6985}")
6986
6987
bb621ad7
JW
6988(define_insn "ashrdi3_internal4"
6989 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 6990 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 6991 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 6992 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
6993 "*
6994{
6995 if (GET_CODE (operands[2]) == CONST_INT)
6996 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6997
6998 return \"dsra\\t%0,%1,%2\";
6999}"
7000 [(set_attr "type" "arith")
0ff83799 7001 (set_attr "mode" "DI")])
bb621ad7 7002
2bcb2ab3
GK
7003(define_insn ""
7004 [(set (match_operand:DI 0 "register_operand" "=d,d")
7005 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7006 (match_operand:SI 2 "arith_operand" "d,I")))]
7007 "TARGET_64BIT && TARGET_MIPS16"
7008 "*
7009{
7010 if (GET_CODE (operands[2]) == CONST_INT)
7011 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7012
7013 return \"dsra\\t%0,%2\";
7014}"
7015 [(set_attr "type" "arith")
7016 (set_attr "mode" "DI")
7017 (set_attr_alternative "length"
0ff83799 7018 [(const_int 4)
2bcb2ab3 7019 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7020 (const_int 4)
7021 (const_int 8))])])
2bcb2ab3
GK
7022
7023;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
bb621ad7 7024
2bcb2ab3
GK
7025(define_split
7026 [(set (match_operand:DI 0 "register_operand" "")
7027 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7028 (match_operand:SI 2 "const_int_operand" "")))]
7029 "TARGET_MIPS16 && TARGET_64BIT
7030 && reload_completed
7031 && GET_CODE (operands[2]) == CONST_INT
7032 && INTVAL (operands[2]) > 8
7033 && INTVAL (operands[2]) <= 16"
7034 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7035 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7036"
7037{
7038 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7039}")
7040
7041(define_expand "lshrsi3"
8ef30996
MM
7042 [(set (match_operand:SI 0 "register_operand" "=d")
7043 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7044 (match_operand:SI 2 "arith_operand" "dI")))]
7045 ""
2bcb2ab3
GK
7046 "
7047{
7048 /* On the mips16, a shift of more than 8 is a four byte instruction,
7049 so, for a shift between 8 and 16, it is just as fast to do two
7050 shifts of 8 or less. If there is a lot of shifting going on, we
7051 may win in CSE. Otherwise combine will put the shifts back
7052 together again. */
7053 if (TARGET_MIPS16
7054 && optimize
7055 && GET_CODE (operands[2]) == CONST_INT
7056 && INTVAL (operands[2]) > 8
7057 && INTVAL (operands[2]) <= 16)
7058 {
7059 rtx temp = gen_reg_rtx (SImode);
7060
7061 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7062 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7063 GEN_INT (INTVAL (operands[2]) - 8)));
7064 DONE;
7065 }
7066}")
7067
7068(define_insn "lshrsi3_internal1"
7069 [(set (match_operand:SI 0 "register_operand" "=d")
7070 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7071 (match_operand:SI 2 "arith_operand" "dI")))]
7072 "!TARGET_MIPS16"
8ef30996
MM
7073 "*
7074{
7075 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 7076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
7077
7078 return \"srl\\t%0,%1,%2\";
7079}"
7080 [(set_attr "type" "arith")
0ff83799 7081 (set_attr "mode" "SI")])
8ef30996 7082
2bcb2ab3
GK
7083(define_insn "lshrsi3_internal2"
7084 [(set (match_operand:SI 0 "register_operand" "=d,d")
7085 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7086 (match_operand:SI 2 "arith_operand" "d,I")))]
7087 "TARGET_MIPS16"
7088 "*
7089{
7090 if (which_alternative == 0)
7091 return \"srl\\t%0,%2\";
7092
7093 if (GET_CODE (operands[2]) == CONST_INT)
95936d18 7094 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2bcb2ab3
GK
7095
7096 return \"srl\\t%0,%1,%2\";
7097}"
7098 [(set_attr "type" "arith")
7099 (set_attr "mode" "SI")
7100 (set_attr_alternative "length"
0ff83799 7101 [(const_int 4)
2bcb2ab3 7102 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7103 (const_int 4)
7104 (const_int 8))])])
2bcb2ab3
GK
7105
7106
7107;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7108
7109(define_split
7110 [(set (match_operand:SI 0 "register_operand" "")
7111 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7112 (match_operand:SI 2 "const_int_operand" "")))]
7113 "TARGET_MIPS16
7114 && reload_completed
7115 && GET_CODE (operands[2]) == CONST_INT
7116 && INTVAL (operands[2]) > 8
7117 && INTVAL (operands[2]) <= 16"
7118 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7119 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7120"
7121{
7122 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7123}")
7124
7125;; If we load a byte on the mips16 as a bitfield, the resulting
7126;; sequence of instructions is too complicated for combine, because it
7127;; involves four instructions: a load, a shift, a constant load into a
7128;; register, and an and (the key problem here is that the mips16 does
7129;; not have and immediate). We recognize a shift of a load in order
7130;; to make it simple enough for combine to understand.
7131
7132(define_insn ""
1379191a 7133 [(set (match_operand:SI 0 "register_operand" "=d,d")
2bcb2ab3
GK
7134 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7135 (match_operand:SI 2 "immediate_operand" "I,I")))]
7136 "TARGET_MIPS16"
7137 "lw\\t%0,%1\;srl\\t%0,%2"
7138 [(set_attr "type" "load")
7139 (set_attr "mode" "SI")
7140 (set_attr_alternative "length"
7141 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7142 (const_int 8)
7143 (const_int 12))
2bcb2ab3 7144 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7145 (const_int 12)
7146 (const_int 16))])])
2bcb2ab3
GK
7147
7148(define_split
7149 [(set (match_operand:SI 0 "register_operand" "")
7150 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7151 (match_operand:SI 2 "immediate_operand" "")))]
7152 "TARGET_MIPS16"
7153 [(set (match_dup 0) (match_dup 1))
7154 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7155 "")
8ef30996
MM
7156
7157(define_expand "lshrdi3"
7158 [(parallel [(set (match_operand:DI 0 "register_operand" "")
1908a152 7159 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
8ef30996
MM
7160 (match_operand:SI 2 "arith_operand" "")))
7161 (clobber (match_dup 3))])]
2bcb2ab3 7162 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
bb621ad7
JW
7163 "
7164{
7165 if (TARGET_64BIT)
7166 {
2bcb2ab3
GK
7167 /* On the mips16, a shift of more than 8 is a four byte
7168 instruction, so, for a shift between 8 and 16, it is just as
7169 fast to do two shifts of 8 or less. If there is a lot of
7170 shifting going on, we may win in CSE. Otherwise combine will
7171 put the shifts back together again. */
7172 if (TARGET_MIPS16
7173 && optimize
7174 && GET_CODE (operands[2]) == CONST_INT
7175 && INTVAL (operands[2]) > 8
7176 && INTVAL (operands[2]) <= 16)
7177 {
7178 rtx temp = gen_reg_rtx (DImode);
7179
7180 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7181 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7182 GEN_INT (INTVAL (operands[2]) - 8)));
7183 DONE;
7184 }
7185
bb621ad7
JW
7186 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7187 operands[2]));
7188 DONE;
7189 }
7190
7191 operands[3] = gen_reg_rtx (SImode);
7192}")
8ef30996
MM
7193
7194
7195(define_insn "lshrdi3_internal"
7196 [(set (match_operand:DI 0 "register_operand" "=&d")
7197 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7198 (match_operand:SI 2 "register_operand" "d")))
7199 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 7200 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
8ef30996
MM
7201 "*
7202{
7203 operands[4] = const0_rtx;
7204 dslots_jump_total += 3;
7205 dslots_jump_filled += 2;
7206
7207 return \"sll\\t%3,%2,26\\n\\
7208\\tbgez\\t%3,1f\\n\\
7209\\tsrl\\t%L0,%M1,%2\\n\\
7210\\t%(b\\t3f\\n\\
7211\\tmove\\t%M0,%z4%)\\n\\
7212\\n\\
efa3896a 7213%~1:\\n\\
8ef30996
MM
7214\\t%(beq\\t%3,%z4,2f\\n\\
7215\\tsrl\\t%L0,%L1,%2%)\\n\\
7216\\n\\
7217\\tsubu\\t%3,%z4,%2\\n\\
7218\\tsll\\t%3,%M1,%3\\n\\
7219\\tor\\t%L0,%L0,%3\\n\\
efa3896a 7220%~2:\\n\\
8ef30996 7221\\tsrl\\t%M0,%M1,%2\\n\\
efa3896a 7222%~3:\";
8ef30996
MM
7223}"
7224 [(set_attr "type" "darith")
7225 (set_attr "mode" "DI")
0ff83799 7226 (set_attr "length" "48")])
8ef30996
MM
7227
7228
7229(define_insn "lshrdi3_internal2"
7230 [(set (match_operand:DI 0 "register_operand" "=d")
7231 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7232 (match_operand:SI 2 "small_int" "IJK")))
7233 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3
GK
7234 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7235 && (INTVAL (operands[2]) & 32) != 0"
8ef30996
MM
7236 "*
7237{
95936d18 7238 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8ef30996
MM
7239 operands[4] = const0_rtx;
7240 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7241}"
7242 [(set_attr "type" "darith")
7243 (set_attr "mode" "DI")
0ff83799 7244 (set_attr "length" "8")])
8ef30996
MM
7245
7246
7247(define_split
7248 [(set (match_operand:DI 0 "register_operand" "")
7249 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7250 (match_operand:SI 2 "small_int" "")))
7251 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7252 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7253 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7254 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7255 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7256 && (INTVAL (operands[2]) & 32) != 0"
7257
ddef6bc7
JJ
7258 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
7259 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
8ef30996 7260
95936d18 7261 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
7262
7263
7264(define_split
7265 [(set (match_operand:DI 0 "register_operand" "")
7266 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7267 (match_operand:SI 2 "small_int" "")))
7268 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7269 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7270 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7271 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7272 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7273 && (INTVAL (operands[2]) & 32) != 0"
7274
ddef6bc7 7275 [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
8ef30996
MM
7276 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7277
95936d18 7278 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
8ef30996
MM
7279
7280
7281(define_insn "lshrdi3_internal3"
7282 [(set (match_operand:DI 0 "register_operand" "=d")
7283 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7284 (match_operand:SI 2 "small_int" "IJK")))
7285 (clobber (match_operand:SI 3 "register_operand" "=d"))]
2bcb2ab3 7286 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7287 && (INTVAL (operands[2]) & 63) < 32
7288 && (INTVAL (operands[2]) & 63) != 0"
7289 "*
7290{
7291 int amount = INTVAL (operands[2]);
7292
c5c76735
JL
7293 operands[2] = GEN_INT (amount & 31);
7294 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7295
7296 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7297}"
7298 [(set_attr "type" "darith")
7299 (set_attr "mode" "DI")
0ff83799 7300 (set_attr "length" "16")])
8ef30996
MM
7301
7302
7303(define_split
7304 [(set (match_operand:DI 0 "register_operand" "")
7305 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7306 (match_operand:SI 2 "small_int" "")))
7307 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7308 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7309 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7310 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7311 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7312 && (INTVAL (operands[2]) & 63) < 32
7313 && (INTVAL (operands[2]) & 63) != 0"
7314
7315 [(set (subreg:SI (match_dup 0) 0)
7316 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7317 (match_dup 2)))
7318
7319 (set (match_dup 3)
ddef6bc7 7320 (ashift:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7321 (match_dup 4)))
7322
7323 (set (subreg:SI (match_dup 0) 0)
7324 (ior:SI (subreg:SI (match_dup 0) 0)
7325 (match_dup 3)))
7326
ddef6bc7
JJ
7327 (set (subreg:SI (match_dup 0) 4)
7328 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7329 (match_dup 2)))]
7330 "
7331{
7332 int amount = INTVAL (operands[2]);
c5c76735
JL
7333 operands[2] = GEN_INT (amount & 31);
7334 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7335}")
7336
7337
7338(define_split
7339 [(set (match_operand:DI 0 "register_operand" "")
7340 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7341 (match_operand:SI 2 "small_int" "")))
7342 (clobber (match_operand:SI 3 "register_operand" ""))]
2bcb2ab3
GK
7343 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7344 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
8ef30996
MM
7345 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7346 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7347 && (INTVAL (operands[2]) & 63) < 32
7348 && (INTVAL (operands[2]) & 63) != 0"
7349
ddef6bc7
JJ
7350 [(set (subreg:SI (match_dup 0) 4)
7351 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
8ef30996
MM
7352 (match_dup 2)))
7353
7354 (set (match_dup 3)
7355 (ashift:SI (subreg:SI (match_dup 1) 0)
7356 (match_dup 4)))
7357
ddef6bc7
JJ
7358 (set (subreg:SI (match_dup 0) 4)
7359 (ior:SI (subreg:SI (match_dup 0) 4)
8ef30996
MM
7360 (match_dup 3)))
7361
7362 (set (subreg:SI (match_dup 0) 0)
7363 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7364 (match_dup 2)))]
7365 "
7366{
7367 int amount = INTVAL (operands[2]);
c5c76735
JL
7368 operands[2] = GEN_INT (amount & 31);
7369 operands[4] = GEN_INT ((-amount) & 31);
8ef30996
MM
7370}")
7371
bb621ad7
JW
7372
7373(define_insn "lshrdi3_internal4"
7374 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 7375 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 7376 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 7377 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
7378 "*
7379{
7380 if (GET_CODE (operands[2]) == CONST_INT)
7381 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7382
7383 return \"dsrl\\t%0,%1,%2\";
7384}"
7385 [(set_attr "type" "arith")
0ff83799 7386 (set_attr "mode" "DI")])
bb621ad7 7387
2bcb2ab3
GK
7388(define_insn ""
7389 [(set (match_operand:DI 0 "register_operand" "=d,d")
7390 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7391 (match_operand:SI 2 "arith_operand" "d,I")))]
7392 "TARGET_64BIT && TARGET_MIPS16"
7393 "*
7394{
7395 if (GET_CODE (operands[2]) == CONST_INT)
7396 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7397
7398 return \"dsrl\\t%0,%2\";
7399}"
7400 [(set_attr "type" "arith")
7401 (set_attr "mode" "DI")
7402 (set_attr_alternative "length"
0ff83799 7403 [(const_int 4)
2bcb2ab3 7404 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
0ff83799
MM
7405 (const_int 4)
7406 (const_int 8))])])
2bcb2ab3
GK
7407
7408;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7409
7410(define_split
7411 [(set (match_operand:DI 0 "register_operand" "")
7412 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7413 (match_operand:SI 2 "const_int_operand" "")))]
7414 "TARGET_MIPS16
7415 && reload_completed
7416 && GET_CODE (operands[2]) == CONST_INT
7417 && INTVAL (operands[2]) > 8
7418 && INTVAL (operands[2]) <= 16"
7419 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7420 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7421"
7422{
7423 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7424}")
7425
8ef30996
MM
7426\f
7427;;
7428;; ....................
7429;;
7430;; COMPARISONS
7431;;
7432;; ....................
7433
7434;; Flow here is rather complex:
7435;;
bb621ad7 7436;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
8ef30996
MM
7437;; arguments into the branch_cmp array, and the type into
7438;; branch_type. No RTL is generated.
7439;;
7440;; 2) The appropriate branch define_expand is called, which then
7441;; creates the appropriate RTL for the comparison and branch.
7442;; Different CC modes are used, based on what type of branch is
7443;; done, so that we can constrain things appropriately. There
7444;; are assumptions in the rest of GCC that break if we fold the
7445;; operands into the branchs for integer operations, and use cc0
34b650b3
MM
7446;; for floating point, so we use the fp status register instead.
7447;; If needed, an appropriate temporary is created to hold the
7448;; of the integer compare.
8ef30996
MM
7449
7450(define_expand "cmpsi"
7451 [(set (cc0)
7452 (compare:CC (match_operand:SI 0 "register_operand" "")
7453 (match_operand:SI 1 "arith_operand" "")))]
7454 ""
7455 "
7456{
7457 if (operands[0]) /* avoid unused code message */
7458 {
7459 branch_cmp[0] = operands[0];
7460 branch_cmp[1] = operands[1];
7461 branch_type = CMP_SI;
7462 DONE;
7463 }
7464}")
7465
7466(define_expand "tstsi"
7467 [(set (cc0)
7468 (match_operand:SI 0 "register_operand" ""))]
7469 ""
7470 "
7471{
7472 if (operands[0]) /* avoid unused code message */
7473 {
7474 branch_cmp[0] = operands[0];
7475 branch_cmp[1] = const0_rtx;
7476 branch_type = CMP_SI;
7477 DONE;
7478 }
7479}")
7480
bb621ad7
JW
7481(define_expand "cmpdi"
7482 [(set (cc0)
1908a152
ILT
7483 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7484 (match_operand:DI 1 "se_arith_operand" "")))]
bb621ad7
JW
7485 "TARGET_64BIT"
7486 "
7487{
7488 if (operands[0]) /* avoid unused code message */
7489 {
7490 branch_cmp[0] = operands[0];
7491 branch_cmp[1] = operands[1];
7492 branch_type = CMP_DI;
7493 DONE;
7494 }
7495}")
7496
7497(define_expand "tstdi"
7498 [(set (cc0)
1908a152 7499 (match_operand:DI 0 "se_register_operand" ""))]
bb621ad7
JW
7500 "TARGET_64BIT"
7501 "
7502{
7503 if (operands[0]) /* avoid unused code message */
7504 {
7505 branch_cmp[0] = operands[0];
7506 branch_cmp[1] = const0_rtx;
7507 branch_type = CMP_DI;
7508 DONE;
7509 }
7510}")
7511
8ef30996
MM
7512(define_expand "cmpdf"
7513 [(set (cc0)
b8eb88d0
ILT
7514 (compare:CC (match_operand:DF 0 "register_operand" "")
7515 (match_operand:DF 1 "register_operand" "")))]
46299de9 7516 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8ef30996
MM
7517 "
7518{
7519 if (operands[0]) /* avoid unused code message */
7520 {
7521 branch_cmp[0] = operands[0];
7522 branch_cmp[1] = operands[1];
7523 branch_type = CMP_DF;
7524 DONE;
7525 }
7526}")
7527
8ef30996
MM
7528(define_expand "cmpsf"
7529 [(set (cc0)
b8eb88d0
ILT
7530 (compare:CC (match_operand:SF 0 "register_operand" "")
7531 (match_operand:SF 1 "register_operand" "")))]
8ef30996
MM
7532 "TARGET_HARD_FLOAT"
7533 "
7534{
7535 if (operands[0]) /* avoid unused code message */
7536 {
7537 branch_cmp[0] = operands[0];
7538 branch_cmp[1] = operands[1];
7539 branch_type = CMP_SF;
7540 DONE;
7541 }
7542}")
7543
8ef30996
MM
7544\f
7545;;
7546;; ....................
7547;;
7548;; CONDITIONAL BRANCHES
7549;;
7550;; ....................
7551
0ff83799
MM
7552;; Conditional branches on floating-point equality tests.
7553
7554(define_insn "branch_fp"
8ef30996 7555 [(set (pc)
0ff83799
MM
7556 (if_then_else
7557 (match_operator:CC 0 "cmp_op"
7558 [(match_operand:CC 2 "register_operand" "z")
7559 (const_int 0)])
7560 (label_ref (match_operand 1 "" ""))
7561 (pc)))]
bb621ad7 7562 "TARGET_HARD_FLOAT"
8ef30996
MM
7563 "*
7564{
0ff83799
MM
7565 return mips_output_conditional_branch (insn,
7566 operands,
7567 /*two_operands_p=*/0,
7568 /*float_p=*/1,
7569 /*inverted_p=*/0,
7570 get_attr_length (insn));
8ef30996
MM
7571}"
7572 [(set_attr "type" "branch")
0ff83799 7573 (set_attr "mode" "none")])
8ef30996 7574
0ff83799 7575(define_insn "branch_fp_inverted"
8ef30996 7576 [(set (pc)
0ff83799
MM
7577 (if_then_else
7578 (match_operator:CC 0 "cmp_op"
7579 [(match_operand:CC 2 "register_operand" "z")
7580 (const_int 0)])
7581 (pc)
7582 (label_ref (match_operand 1 "" ""))))]
bb621ad7 7583 "TARGET_HARD_FLOAT"
8ef30996
MM
7584 "*
7585{
0ff83799
MM
7586 return mips_output_conditional_branch (insn,
7587 operands,
7588 /*two_operands_p=*/0,
7589 /*float_p=*/1,
7590 /*inverted_p=*/1,
7591 get_attr_length (insn));
8ef30996
MM
7592}"
7593 [(set_attr "type" "branch")
0ff83799
MM
7594 (set_attr "mode" "none")])
7595
7596;; Conditional branches on comparisons with zero.
8ef30996 7597
34b650b3 7598(define_insn "branch_zero"
8ef30996 7599 [(set (pc)
0ff83799
MM
7600 (if_then_else
7601 (match_operator:SI 0 "cmp_op"
7602 [(match_operand:SI 2 "register_operand" "d")
7603 (const_int 0)])
7604 (label_ref (match_operand 1 "" ""))
7605 (pc)))]
2bcb2ab3 7606 "!TARGET_MIPS16"
8ef30996
MM
7607 "*
7608{
0ff83799
MM
7609 return mips_output_conditional_branch (insn,
7610 operands,
7611 /*two_operands_p=*/0,
7612 /*float_p=*/0,
7613 /*inverted_p=*/0,
7614 get_attr_length (insn));
7615}"
7616 [(set_attr "type" "branch")
7617 (set_attr "mode" "none")])
8ef30996 7618
0ff83799
MM
7619(define_insn "branch_zero_inverted"
7620 [(set (pc)
7621 (if_then_else
7622 (match_operator:SI 0 "cmp_op"
7623 [(match_operand:SI 2 "register_operand" "d")
7624 (const_int 0)])
7625 (pc)
7626 (label_ref (match_operand 1 "" ""))))]
7627 "!TARGET_MIPS16"
7628 "*
7629{
7630 return mips_output_conditional_branch (insn,
7631 operands,
7632 /*two_operands_p=*/0,
7633 /*float_p=*/0,
7634 /*inverted_p=*/1,
7635 get_attr_length (insn));
7636}"
7637 [(set_attr "type" "branch")
7638 (set_attr "mode" "none")])
8ef30996 7639
0ff83799
MM
7640(define_insn "branch_zero_di"
7641 [(set (pc)
7642 (if_then_else
7643 (match_operator:DI 0 "cmp_op"
7644 [(match_operand:DI 2 "se_register_operand" "d")
7645 (const_int 0)])
7646 (label_ref (match_operand 1 "" ""))
7647 (pc)))]
7648 "!TARGET_MIPS16"
7649 "*
7650{
7651 return mips_output_conditional_branch (insn,
7652 operands,
7653 /*two_operands_p=*/0,
7654 /*float_p=*/0,
7655 /*inverted_p=*/0,
7656 get_attr_length (insn));
8ef30996
MM
7657}"
7658 [(set_attr "type" "branch")
0ff83799
MM
7659 (set_attr "mode" "none")])
7660
7661(define_insn "branch_zero_di_inverted"
7662 [(set (pc)
7663 (if_then_else
7664 (match_operator:DI 0 "cmp_op"
7665 [(match_operand:DI 2 "se_register_operand" "d")
7666 (const_int 0)])
7667 (pc)
7668 (label_ref (match_operand 1 "" ""))))]
7669 "!TARGET_MIPS16"
7670 "*
7671{
7672 return mips_output_conditional_branch (insn,
7673 operands,
7674 /*two_operands_p=*/0,
7675 /*float_p=*/0,
7676 /*inverted_p=*/1,
7677 get_attr_length (insn));
7678}"
7679 [(set_attr "type" "branch")
7680 (set_attr "mode" "none")])
7681
7682;; Conditional branch on equality comparision.
7683
7684(define_insn "branch_equality"
7685 [(set (pc)
7686 (if_then_else
7687 (match_operator:SI 0 "equality_op"
7688 [(match_operand:SI 2 "register_operand" "d")
7689 (match_operand:SI 3 "register_operand" "d")])
7690 (label_ref (match_operand 1 "" ""))
7691 (pc)))]
7692 "!TARGET_MIPS16"
7693 "*
7694{
7695 return mips_output_conditional_branch (insn,
7696 operands,
7697 /*two_operands_p=*/1,
7698 /*float_p=*/0,
7699 /*inverted_p=*/0,
7700 get_attr_length (insn));
7701}"
7702 [(set_attr "type" "branch")
7703 (set_attr "mode" "none")])
7704
7705(define_insn "branch_equality_di"
7706 [(set (pc)
7707 (if_then_else
7708 (match_operator:DI 0 "equality_op"
7709 [(match_operand:DI 2 "se_register_operand" "d")
7710 (match_operand:DI 3 "se_register_operand" "d")])
7711 (label_ref (match_operand 1 "" ""))
7712 (pc)))]
7713 "!TARGET_MIPS16"
7714 "*
7715{
7716 return mips_output_conditional_branch (insn,
7717 operands,
7718 /*two_operands_p=*/1,
7719 /*float_p=*/0,
7720 /*inverted_p=*/0,
7721 get_attr_length (insn));
7722}"
7723 [(set_attr "type" "branch")
7724 (set_attr "mode" "none")])
7725
7726(define_insn "branch_equality_inverted"
7727 [(set (pc)
7728 (if_then_else
7729 (match_operator:SI 0 "equality_op"
7730 [(match_operand:SI 2 "register_operand" "d")
7731 (match_operand:SI 3 "register_operand" "d")])
7732 (pc)
7733 (label_ref (match_operand 1 "" ""))))]
7734 "!TARGET_MIPS16"
7735 "*
7736{
7737 return mips_output_conditional_branch (insn,
7738 operands,
7739 /*two_operands_p=*/1,
7740 /*float_p=*/0,
7741 /*inverted_p=*/1,
7742 get_attr_length (insn));
7743}"
7744 [(set_attr "type" "branch")
7745 (set_attr "mode" "none")])
7746
7747(define_insn "branch_equality_di_inverted"
7748 [(set (pc)
7749 (if_then_else
7750 (match_operator:DI 0 "equality_op"
7751 [(match_operand:DI 2 "se_register_operand" "d")
7752 (match_operand:DI 3 "se_register_operand" "d")])
7753 (pc)
7754 (label_ref (match_operand 1 "" ""))))]
7755 "!TARGET_MIPS16"
7756 "*
7757{
7758 return mips_output_conditional_branch (insn,
7759 operands,
7760 /*two_operands_p=*/1,
7761 /*float_p=*/0,
7762 /*inverted_p=*/1,
7763 get_attr_length (insn));
7764}"
7765 [(set_attr "type" "branch")
7766 (set_attr "mode" "none")])
8ef30996 7767
0ff83799 7768;; MIPS16 branches
8ef30996 7769
2bcb2ab3
GK
7770(define_insn ""
7771 [(set (pc)
7772 (if_then_else (match_operator:SI 0 "equality_op"
7773 [(match_operand:SI 1 "register_operand" "d,t")
7774 (const_int 0)])
7775 (match_operand 2 "pc_or_label_operand" "")
7776 (match_operand 3 "pc_or_label_operand" "")))]
7777 "TARGET_MIPS16"
7778 "*
7779{
7780 if (operands[2] != pc_rtx)
7781 {
7782 if (which_alternative == 0)
7783 return \"%*b%C0z\\t%1,%2\";
7784 else
7785 return \"%*bt%C0z\\t%2\";
7786 }
7787 else
7788 {
7789 if (which_alternative == 0)
7790 return \"%*b%N0z\\t%1,%3\";
7791 else
7792 return \"%*bt%N0z\\t%3\";
7793 }
7794}"
7795 [(set_attr "type" "branch")
7796 (set_attr "mode" "none")
0ff83799 7797 (set_attr "length" "8")])
bb621ad7 7798
2bcb2ab3
GK
7799(define_insn ""
7800 [(set (pc)
7801 (if_then_else (match_operator:DI 0 "equality_op"
7802 [(match_operand:DI 1 "se_register_operand" "d,t")
7803 (const_int 0)])
7804 (match_operand 2 "pc_or_label_operand" "")
7805 (match_operand 3 "pc_or_label_operand" "")))]
7806 "TARGET_MIPS16"
7807 "*
7808{
7809 if (operands[2] != pc_rtx)
7810 {
7811 if (which_alternative == 0)
7812 return \"%*b%C0z\\t%1,%2\";
7813 else
7814 return \"%*bt%C0z\\t%2\";
7815 }
7816 else
7817 {
7818 if (which_alternative == 0)
7819 return \"%*b%N0z\\t%1,%3\";
7820 else
7821 return \"%*bt%N0z\\t%3\";
7822 }
7823}"
7824 [(set_attr "type" "branch")
7825 (set_attr "mode" "none")
0ff83799 7826 (set_attr "length" "8")])
bb621ad7 7827
8ef30996
MM
7828(define_expand "beq"
7829 [(set (pc)
b8eb88d0
ILT
7830 (if_then_else (eq:CC (cc0)
7831 (const_int 0))
8ef30996
MM
7832 (label_ref (match_operand 0 "" ""))
7833 (pc)))]
7834 ""
7835 "
7836{
7837 if (operands[0]) /* avoid unused code warning */
7838 {
7839 gen_conditional_branch (operands, EQ);
7840 DONE;
7841 }
7842}")
7843
7844(define_expand "bne"
7845 [(set (pc)
b8eb88d0
ILT
7846 (if_then_else (ne:CC (cc0)
7847 (const_int 0))
8ef30996
MM
7848 (label_ref (match_operand 0 "" ""))
7849 (pc)))]
7850 ""
7851 "
7852{
7853 if (operands[0]) /* avoid unused code warning */
7854 {
7855 gen_conditional_branch (operands, NE);
7856 DONE;
7857 }
7858}")
7859
7860(define_expand "bgt"
7861 [(set (pc)
7862 (if_then_else (gt:CC (cc0)
7863 (const_int 0))
7864 (label_ref (match_operand 0 "" ""))
7865 (pc)))]
7866 ""
7867 "
7868{
7869 if (operands[0]) /* avoid unused code warning */
7870 {
7871 gen_conditional_branch (operands, GT);
7872 DONE;
7873 }
7874}")
7875
7876(define_expand "bge"
7877 [(set (pc)
7878 (if_then_else (ge:CC (cc0)
7879 (const_int 0))
7880 (label_ref (match_operand 0 "" ""))
7881 (pc)))]
7882 ""
7883 "
7884{
7885 if (operands[0]) /* avoid unused code warning */
7886 {
7887 gen_conditional_branch (operands, GE);
7888 DONE;
7889 }
7890}")
7891
7892(define_expand "blt"
7893 [(set (pc)
7894 (if_then_else (lt:CC (cc0)
7895 (const_int 0))
7896 (label_ref (match_operand 0 "" ""))
7897 (pc)))]
7898 ""
7899 "
7900{
7901 if (operands[0]) /* avoid unused code warning */
7902 {
7903 gen_conditional_branch (operands, LT);
7904 DONE;
7905 }
7906}")
7907
7908(define_expand "ble"
7909 [(set (pc)
7910 (if_then_else (le:CC (cc0)
7911 (const_int 0))
7912 (label_ref (match_operand 0 "" ""))
7913 (pc)))]
7914 ""
7915 "
7916{
7917 if (operands[0]) /* avoid unused code warning */
7918 {
7919 gen_conditional_branch (operands, LE);
7920 DONE;
7921 }
7922}")
7923
7924(define_expand "bgtu"
7925 [(set (pc)
7926 (if_then_else (gtu:CC (cc0)
7927 (const_int 0))
7928 (label_ref (match_operand 0 "" ""))
7929 (pc)))]
7930 ""
7931 "
7932{
7933 if (operands[0]) /* avoid unused code warning */
7934 {
7935 gen_conditional_branch (operands, GTU);
7936 DONE;
7937 }
7938}")
7939
7940(define_expand "bgeu"
7941 [(set (pc)
7942 (if_then_else (geu:CC (cc0)
7943 (const_int 0))
7944 (label_ref (match_operand 0 "" ""))
7945 (pc)))]
7946 ""
7947 "
7948{
7949 if (operands[0]) /* avoid unused code warning */
7950 {
7951 gen_conditional_branch (operands, GEU);
7952 DONE;
7953 }
7954}")
7955
7956
7957(define_expand "bltu"
7958 [(set (pc)
7959 (if_then_else (ltu:CC (cc0)
7960 (const_int 0))
7961 (label_ref (match_operand 0 "" ""))
7962 (pc)))]
7963 ""
7964 "
7965{
7966 if (operands[0]) /* avoid unused code warning */
7967 {
7968 gen_conditional_branch (operands, LTU);
7969 DONE;
7970 }
7971}")
7972
7973(define_expand "bleu"
7974 [(set (pc)
7975 (if_then_else (leu:CC (cc0)
7976 (const_int 0))
7977 (label_ref (match_operand 0 "" ""))
7978 (pc)))]
7979 ""
7980 "
7981{
7982 if (operands[0]) /* avoid unused code warning */
7983 {
7984 gen_conditional_branch (operands, LEU);
7985 DONE;
7986 }
7987}")
7988
7989\f
7990;;
7991;; ....................
7992;;
7993;; SETTING A REGISTER FROM A COMPARISON
7994;;
7995;; ....................
7996
7997(define_expand "seq"
7998 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3
MM
7999 (eq:SI (match_dup 1)
8000 (match_dup 2)))]
8ef30996
MM
8001 ""
8002 "
8003{
bb621ad7 8004 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8005 FAIL;
8006
8007 /* set up operands from compare. */
8008 operands[1] = branch_cmp[0];
8009 operands[2] = branch_cmp[1];
8010
2bcb2ab3 8011 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8012 {
8013 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8014 DONE;
8015 }
8016
8ef30996
MM
8017 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8018 operands[2] = force_reg (SImode, operands[2]);
8019
8020 /* fall through and generate default code */
8021}")
8022
34b650b3
MM
8023
8024(define_insn "seq_si_zero"
8025 [(set (match_operand:SI 0 "register_operand" "=d")
8026 (eq:SI (match_operand:SI 1 "register_operand" "d")
8027 (const_int 0)))]
2bcb2ab3 8028 "!TARGET_MIPS16"
34b650b3 8029 "sltu\\t%0,%1,1"
bb621ad7 8030 [(set_attr "type" "arith")
0ff83799 8031 (set_attr "mode" "SI")])
34b650b3 8032
2bcb2ab3
GK
8033(define_insn ""
8034 [(set (match_operand:SI 0 "register_operand" "=t")
8035 (eq:SI (match_operand:SI 1 "register_operand" "d")
8036 (const_int 0)))]
8037 "TARGET_MIPS16"
8038 "sltu\\t%1,1"
8039 [(set_attr "type" "arith")
0ff83799 8040 (set_attr "mode" "SI")])
2bcb2ab3 8041
bb621ad7
JW
8042(define_insn "seq_di_zero"
8043 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 8044 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 8045 (const_int 0)))]
2bcb2ab3 8046 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8047 "sltu\\t%0,%1,1"
8048 [(set_attr "type" "arith")
0ff83799 8049 (set_attr "mode" "DI")])
bb621ad7 8050
2bcb2ab3
GK
8051(define_insn ""
8052 [(set (match_operand:DI 0 "register_operand" "=t")
8053 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8054 (const_int 0)))]
8055 "TARGET_64BIT && TARGET_MIPS16"
8056 "sltu\\t%1,1"
8057 [(set_attr "type" "arith")
0ff83799 8058 (set_attr "mode" "DI")])
2bcb2ab3 8059
34b650b3
MM
8060(define_insn "seq_si"
8061 [(set (match_operand:SI 0 "register_operand" "=d,d")
8062 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8063 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 8064 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8ef30996 8065 "@
8ef30996 8066 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
34b650b3 8067 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
bb621ad7
JW
8068 [(set_attr "type" "arith")
8069 (set_attr "mode" "SI")
0ff83799 8070 (set_attr "length" "8")])
bb621ad7
JW
8071
8072(define_split
8073 [(set (match_operand:SI 0 "register_operand" "")
8074 (eq:SI (match_operand:SI 1 "register_operand" "")
8075 (match_operand:SI 2 "uns_arith_operand" "")))]
2bcb2ab3 8076 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
bb621ad7
JW
8077 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8078 [(set (match_dup 0)
8079 (xor:SI (match_dup 1)
8080 (match_dup 2)))
8081 (set (match_dup 0)
8082 (ltu:SI (match_dup 0)
8083 (const_int 1)))]
8084 "")
8085
8086(define_insn "seq_di"
8087 [(set (match_operand:DI 0 "register_operand" "=d,d")
1908a152
ILT
8088 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8089 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2bcb2ab3 8090 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8091 "@
8092 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8093 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8094 [(set_attr "type" "arith")
8095 (set_attr "mode" "DI")
0ff83799 8096 (set_attr "length" "8")])
8ef30996
MM
8097
8098(define_split
bb621ad7 8099 [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
8100 (eq:DI (match_operand:DI 1 "se_register_operand" "")
8101 (match_operand:DI 2 "se_uns_arith_operand" "")))]
bb621ad7 8102 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
2bcb2ab3 8103 && !TARGET_MIPS16
26b8e6e5 8104 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8ef30996 8105 [(set (match_dup 0)
bb621ad7 8106 (xor:DI (match_dup 1)
8ef30996
MM
8107 (match_dup 2)))
8108 (set (match_dup 0)
bb621ad7 8109 (ltu:DI (match_dup 0)
8ef30996
MM
8110 (const_int 1)))]
8111 "")
8112
2bcb2ab3
GK
8113;; On the mips16 the default code is better than using sltu.
8114
8ef30996
MM
8115(define_expand "sne"
8116 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3
MM
8117 (ne:SI (match_dup 1)
8118 (match_dup 2)))]
2bcb2ab3 8119 "!TARGET_MIPS16"
8ef30996
MM
8120 "
8121{
bb621ad7 8122 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8123 FAIL;
8124
8125 /* set up operands from compare. */
8126 operands[1] = branch_cmp[0];
8127 operands[2] = branch_cmp[1];
8128
bb621ad7 8129 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
34b650b3
MM
8130 {
8131 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8132 DONE;
8133 }
8134
8ef30996
MM
8135 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8136 operands[2] = force_reg (SImode, operands[2]);
8137
8138 /* fall through and generate default code */
8139}")
8140
34b650b3
MM
8141(define_insn "sne_si_zero"
8142 [(set (match_operand:SI 0 "register_operand" "=d")
8143 (ne:SI (match_operand:SI 1 "register_operand" "d")
8144 (const_int 0)))]
2bcb2ab3 8145 "!TARGET_MIPS16"
34b650b3 8146 "sltu\\t%0,%.,%1"
bb621ad7 8147 [(set_attr "type" "arith")
0ff83799 8148 (set_attr "mode" "SI")])
8ef30996 8149
bb621ad7
JW
8150(define_insn "sne_di_zero"
8151 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 8152 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 8153 (const_int 0)))]
2bcb2ab3 8154 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8155 "sltu\\t%0,%.,%1"
8156 [(set_attr "type" "arith")
0ff83799 8157 (set_attr "mode" "DI")])
bb621ad7 8158
34b650b3
MM
8159(define_insn "sne_si"
8160 [(set (match_operand:SI 0 "register_operand" "=d,d")
8161 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8162 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2bcb2ab3 8163 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
34b650b3
MM
8164 "@
8165 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8166 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
bb621ad7 8167 [(set_attr "type" "arith")
92b4cee1 8168 (set_attr "mode" "SI")
0ff83799 8169 (set_attr "length" "8")])
8ef30996
MM
8170
8171(define_split
8172 [(set (match_operand:SI 0 "register_operand" "")
34b650b3
MM
8173 (ne:SI (match_operand:SI 1 "register_operand" "")
8174 (match_operand:SI 2 "uns_arith_operand" "")))]
2bcb2ab3 8175 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
26b8e6e5 8176 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8ef30996
MM
8177 [(set (match_dup 0)
8178 (xor:SI (match_dup 1)
8179 (match_dup 2)))
8180 (set (match_dup 0)
34b650b3 8181 (gtu:SI (match_dup 0)
8ef30996
MM
8182 (const_int 0)))]
8183 "")
8184
bb621ad7
JW
8185(define_insn "sne_di"
8186 [(set (match_operand:DI 0 "register_operand" "=d,d")
1908a152
ILT
8187 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8188 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2bcb2ab3 8189 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8190 "@
8191 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8192 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8193 [(set_attr "type" "arith")
8194 (set_attr "mode" "DI")
0ff83799 8195 (set_attr "length" "8")])
bb621ad7
JW
8196
8197(define_split
8198 [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
8199 (ne:DI (match_operand:DI 1 "se_register_operand" "")
8200 (match_operand:DI 2 "se_uns_arith_operand" "")))]
bb621ad7 8201 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
2bcb2ab3 8202 && !TARGET_MIPS16
bb621ad7
JW
8203 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8204 [(set (match_dup 0)
8205 (xor:DI (match_dup 1)
8206 (match_dup 2)))
8207 (set (match_dup 0)
8208 (gtu:DI (match_dup 0)
8209 (const_int 0)))]
8210 "")
8211
8ef30996
MM
8212(define_expand "sgt"
8213 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8214 (gt:SI (match_dup 1)
8ef30996
MM
8215 (match_dup 2)))]
8216 ""
8217 "
8218{
bb621ad7 8219 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8220 FAIL;
8221
8222 /* set up operands from compare. */
8223 operands[1] = branch_cmp[0];
8224 operands[2] = branch_cmp[1];
8225
2bcb2ab3 8226 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8227 {
8228 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8229 DONE;
8230 }
8231
8ef30996
MM
8232 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8233 operands[2] = force_reg (SImode, operands[2]);
8234
8235 /* fall through and generate default code */
8236}")
8237
8238(define_insn "sgt_si"
8239 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8240 (gt:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8241 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
2bcb2ab3 8242 "!TARGET_MIPS16"
8ef30996 8243 "slt\\t%0,%z2,%1"
bb621ad7 8244 [(set_attr "type" "arith")
0ff83799 8245 (set_attr "mode" "SI")])
8ef30996 8246
2bcb2ab3
GK
8247(define_insn ""
8248 [(set (match_operand:SI 0 "register_operand" "=t")
8249 (gt:SI (match_operand:SI 1 "register_operand" "d")
8250 (match_operand:SI 2 "register_operand" "d")))]
8251 "TARGET_MIPS16"
8252 "slt\\t%2,%1"
8253 [(set_attr "type" "arith")
0ff83799 8254 (set_attr "mode" "SI")])
2bcb2ab3 8255
bb621ad7
JW
8256(define_insn "sgt_di"
8257 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8258 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8259 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
2bcb2ab3 8260 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8261 "slt\\t%0,%z2,%1"
8262 [(set_attr "type" "arith")
0ff83799 8263 (set_attr "mode" "DI")])
bb621ad7 8264
2bcb2ab3
GK
8265(define_insn ""
8266 [(set (match_operand:DI 0 "register_operand" "=d")
8267 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8268 (match_operand:DI 2 "se_register_operand" "d")))]
8269 "TARGET_64BIT && TARGET_MIPS16"
8270 "slt\\t%2,%1"
8271 [(set_attr "type" "arith")
0ff83799 8272 (set_attr "mode" "DI")])
2bcb2ab3 8273
8ef30996
MM
8274(define_expand "sge"
8275 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8276 (ge:SI (match_dup 1)
8ef30996
MM
8277 (match_dup 2)))]
8278 ""
8279 "
8280{
bb621ad7 8281 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8282 FAIL;
8283
8284 /* set up operands from compare. */
8285 operands[1] = branch_cmp[0];
8286 operands[2] = branch_cmp[1];
8287
2bcb2ab3 8288 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8289 {
8290 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8291 DONE;
8292 }
8293
8ef30996
MM
8294 /* fall through and generate default code */
8295}")
8296
8297(define_insn "sge_si"
8298 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8299 (ge:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8300 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8301 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8ef30996 8302 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
bb621ad7 8303 [(set_attr "type" "arith")
8ef30996 8304 (set_attr "mode" "SI")
0ff83799 8305 (set_attr "length" "8")])
8ef30996
MM
8306
8307(define_split
8308 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8309 (ge:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8310 (match_operand:SI 2 "arith_operand" "")))]
2bcb2ab3 8311 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8312 [(set (match_dup 0)
34b650b3 8313 (lt:SI (match_dup 1)
8ef30996
MM
8314 (match_dup 2)))
8315 (set (match_dup 0)
8316 (xor:SI (match_dup 0)
8317 (const_int 1)))]
8318 "")
8319
bb621ad7
JW
8320(define_insn "sge_di"
8321 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8322 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8323 (match_operand:DI 2 "se_arith_operand" "dI")))]
2bcb2ab3 8324 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8325 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8326 [(set_attr "type" "arith")
8327 (set_attr "mode" "DI")
0ff83799 8328 (set_attr "length" "8")])
bb621ad7
JW
8329
8330(define_split
8331 [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
8332 (ge:DI (match_operand:DI 1 "se_register_operand" "")
8333 (match_operand:DI 2 "se_arith_operand" "")))]
2bcb2ab3
GK
8334 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8335 && !TARGET_MIPS16"
bb621ad7
JW
8336 [(set (match_dup 0)
8337 (lt:DI (match_dup 1)
8338 (match_dup 2)))
8339 (set (match_dup 0)
8340 (xor:DI (match_dup 0)
8341 (const_int 1)))]
8342 "")
8343
8ef30996
MM
8344(define_expand "slt"
8345 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8346 (lt:SI (match_dup 1)
8ef30996
MM
8347 (match_dup 2)))]
8348 ""
8349 "
8350{
bb621ad7 8351 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8352 FAIL;
8353
8354 /* set up operands from compare. */
8355 operands[1] = branch_cmp[0];
8356 operands[2] = branch_cmp[1];
8357
2bcb2ab3 8358 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8359 {
8360 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8361 DONE;
8362 }
8363
8ef30996
MM
8364 /* fall through and generate default code */
8365}")
8366
8367(define_insn "slt_si"
8368 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8369 (lt:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8370 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8371 "!TARGET_MIPS16"
8ef30996 8372 "slt\\t%0,%1,%2"
bb621ad7 8373 [(set_attr "type" "arith")
0ff83799 8374 (set_attr "mode" "SI")])
8ef30996 8375
2bcb2ab3
GK
8376(define_insn ""
8377 [(set (match_operand:SI 0 "register_operand" "=t,t")
8378 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8379 (match_operand:SI 2 "arith_operand" "d,I")))]
8380 "TARGET_MIPS16"
8381 "slt\\t%1,%2"
8382 [(set_attr "type" "arith")
8383 (set_attr "mode" "SI")
8384 (set_attr_alternative "length"
0ff83799 8385 [(const_int 4)
2bcb2ab3 8386 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8387 (const_int 4)
8388 (const_int 8))])])
2bcb2ab3 8389
bb621ad7
JW
8390(define_insn "slt_di"
8391 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8392 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8393 (match_operand:DI 2 "se_arith_operand" "dI")))]
2bcb2ab3 8394 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8395 "slt\\t%0,%1,%2"
8396 [(set_attr "type" "arith")
0ff83799 8397 (set_attr "mode" "DI")])
bb621ad7 8398
2bcb2ab3
GK
8399(define_insn ""
8400 [(set (match_operand:DI 0 "register_operand" "=t,t")
8401 (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8402 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8403 "TARGET_64BIT && TARGET_MIPS16"
8404 "slt\\t%1,%2"
8405 [(set_attr "type" "arith")
8406 (set_attr "mode" "DI")
8407 (set_attr_alternative "length"
0ff83799 8408 [(const_int 4)
2bcb2ab3 8409 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8410 (const_int 4)
8411 (const_int 8))])])
2bcb2ab3 8412
8ef30996
MM
8413(define_expand "sle"
8414 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8415 (le:SI (match_dup 1)
8ef30996
MM
8416 (match_dup 2)))]
8417 ""
8418 "
8419{
bb621ad7 8420 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8421 FAIL;
8422
8423 /* set up operands from compare. */
8424 operands[1] = branch_cmp[0];
8425 operands[2] = branch_cmp[1];
8426
2bcb2ab3 8427 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8428 {
8429 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8430 DONE;
8431 }
8432
8ef30996
MM
8433 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8434 operands[2] = force_reg (SImode, operands[2]);
8435
8436 /* fall through and generate default code */
8437}")
8438
34b650b3
MM
8439(define_insn "sle_si_const"
8440 [(set (match_operand:SI 0 "register_operand" "=d")
8441 (le:SI (match_operand:SI 1 "register_operand" "d")
8442 (match_operand:SI 2 "small_int" "I")))]
2bcb2ab3 8443 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
34b650b3
MM
8444 "*
8445{
95936d18 8446 operands[2] = GEN_INT (INTVAL (operands[2])+1);
34b650b3
MM
8447 return \"slt\\t%0,%1,%2\";
8448}"
bb621ad7 8449 [(set_attr "type" "arith")
0ff83799 8450 (set_attr "mode" "SI")])
34b650b3 8451
2bcb2ab3
GK
8452(define_insn ""
8453 [(set (match_operand:SI 0 "register_operand" "=t")
8454 (le:SI (match_operand:SI 1 "register_operand" "d")
8455 (match_operand:SI 2 "small_int" "I")))]
8456 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8457 "*
8458{
95936d18 8459 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
8460 return \"slt\\t%1,%2\";
8461}"
8462 [(set_attr "type" "arith")
8463 (set_attr "mode" "SI")
8464 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
8465 (const_int 4)
8466 (const_int 8)))])
2bcb2ab3 8467
bb621ad7
JW
8468(define_insn "sle_di_const"
8469 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 8470 (le:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 8471 (match_operand:DI 2 "small_int" "I")))]
2bcb2ab3 8472 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
bb621ad7
JW
8473 "*
8474{
95936d18 8475 operands[2] = GEN_INT (INTVAL (operands[2])+1);
bb621ad7
JW
8476 return \"slt\\t%0,%1,%2\";
8477}"
8478 [(set_attr "type" "arith")
0ff83799 8479 (set_attr "mode" "DI")])
bb621ad7 8480
2bcb2ab3
GK
8481(define_insn ""
8482 [(set (match_operand:DI 0 "register_operand" "=t")
8483 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8484 (match_operand:DI 2 "small_int" "I")))]
8485 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8486 "*
8487{
95936d18 8488 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
8489 return \"slt\\t%1,%2\";
8490}"
8491 [(set_attr "type" "arith")
8492 (set_attr "mode" "DI")
8493 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
8494 (const_int 4)
8495 (const_int 8)))])
2bcb2ab3 8496
34b650b3
MM
8497(define_insn "sle_si_reg"
8498 [(set (match_operand:SI 0 "register_operand" "=d")
8499 (le:SI (match_operand:SI 1 "register_operand" "d")
8500 (match_operand:SI 2 "register_operand" "d")))]
2bcb2ab3 8501 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
34b650b3 8502 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
bb621ad7 8503 [(set_attr "type" "arith")
34b650b3 8504 (set_attr "mode" "SI")
0ff83799 8505 (set_attr "length" "8")])
8ef30996
MM
8506
8507(define_split
8508 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8509 (le:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8510 (match_operand:SI 2 "register_operand" "")))]
2bcb2ab3 8511 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8512 [(set (match_dup 0)
34b650b3 8513 (lt:SI (match_dup 2)
8ef30996
MM
8514 (match_dup 1)))
8515 (set (match_dup 0)
8516 (xor:SI (match_dup 0)
8517 (const_int 1)))]
8518 "")
8519
bb621ad7
JW
8520(define_insn "sle_di_reg"
8521 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8522 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8523 (match_operand:DI 2 "se_register_operand" "d")))]
2bcb2ab3 8524 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8525 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8526 [(set_attr "type" "arith")
8527 (set_attr "mode" "DI")
0ff83799 8528 (set_attr "length" "8")])
bb621ad7
JW
8529
8530(define_split
8531 [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
8532 (le:DI (match_operand:DI 1 "se_register_operand" "")
8533 (match_operand:DI 2 "se_register_operand" "")))]
2bcb2ab3
GK
8534 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8535 && !TARGET_MIPS16"
bb621ad7
JW
8536 [(set (match_dup 0)
8537 (lt:DI (match_dup 2)
8538 (match_dup 1)))
8539 (set (match_dup 0)
8540 (xor:DI (match_dup 0)
8541 (const_int 1)))]
8542 "")
8543
8ef30996
MM
8544(define_expand "sgtu"
8545 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8546 (gtu:SI (match_dup 1)
8ef30996
MM
8547 (match_dup 2)))]
8548 ""
8549 "
8550{
bb621ad7 8551 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8552 FAIL;
8553
8554 /* set up operands from compare. */
8555 operands[1] = branch_cmp[0];
8556 operands[2] = branch_cmp[1];
8557
2bcb2ab3 8558 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8559 {
8560 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8561 DONE;
8562 }
8563
8ef30996
MM
8564 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8565 operands[2] = force_reg (SImode, operands[2]);
8566
8567 /* fall through and generate default code */
8568}")
8569
8570(define_insn "sgtu_si"
8571 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8572 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996
MM
8573 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8574 ""
8575 "sltu\\t%0,%z2,%1"
bb621ad7 8576 [(set_attr "type" "arith")
0ff83799 8577 (set_attr "mode" "SI")])
8ef30996 8578
2bcb2ab3
GK
8579(define_insn ""
8580 [(set (match_operand:SI 0 "register_operand" "=t")
8581 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8582 (match_operand:SI 2 "register_operand" "d")))]
8583 ""
8584 "sltu\\t%2,%1"
8585 [(set_attr "type" "arith")
0ff83799 8586 (set_attr "mode" "SI")])
2bcb2ab3 8587
bb621ad7
JW
8588(define_insn "sgtu_di"
8589 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8590 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8591 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
bb621ad7
JW
8592 "TARGET_64BIT"
8593 "sltu\\t%0,%z2,%1"
8594 [(set_attr "type" "arith")
0ff83799 8595 (set_attr "mode" "DI")])
bb621ad7 8596
2bcb2ab3
GK
8597(define_insn ""
8598 [(set (match_operand:DI 0 "register_operand" "=t")
8599 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8600 (match_operand:DI 2 "se_register_operand" "d")))]
8601 "TARGET_64BIT"
8602 "sltu\\t%2,%1"
8603 [(set_attr "type" "arith")
0ff83799 8604 (set_attr "mode" "DI")])
2bcb2ab3 8605
8ef30996
MM
8606(define_expand "sgeu"
8607 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8608 (geu:SI (match_dup 1)
8ef30996
MM
8609 (match_dup 2)))]
8610 ""
8611 "
8612{
bb621ad7 8613 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8614 FAIL;
8615
8616 /* set up operands from compare. */
8617 operands[1] = branch_cmp[0];
8618 operands[2] = branch_cmp[1];
8619
2bcb2ab3 8620 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8621 {
8622 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8623 DONE;
8624 }
8625
8ef30996
MM
8626 /* fall through and generate default code */
8627}")
8628
8629(define_insn "sgeu_si"
8630 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8631 (geu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8632 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8633 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8ef30996 8634 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
bb621ad7 8635 [(set_attr "type" "arith")
8ef30996 8636 (set_attr "mode" "SI")
0ff83799 8637 (set_attr "length" "8")])
8ef30996
MM
8638
8639(define_split
8640 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8641 (geu:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8642 (match_operand:SI 2 "arith_operand" "")))]
2bcb2ab3 8643 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8644 [(set (match_dup 0)
34b650b3 8645 (ltu:SI (match_dup 1)
8ef30996
MM
8646 (match_dup 2)))
8647 (set (match_dup 0)
8648 (xor:SI (match_dup 0)
8649 (const_int 1)))]
8650 "")
8651
bb621ad7
JW
8652(define_insn "sgeu_di"
8653 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8654 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8655 (match_operand:DI 2 "se_arith_operand" "dI")))]
2bcb2ab3 8656 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8657 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8658 [(set_attr "type" "arith")
8659 (set_attr "mode" "DI")
0ff83799 8660 (set_attr "length" "8")])
bb621ad7
JW
8661
8662(define_split
8663 [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
8664 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8665 (match_operand:DI 2 "se_arith_operand" "")))]
2bcb2ab3
GK
8666 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8667 && !TARGET_MIPS16"
bb621ad7
JW
8668 [(set (match_dup 0)
8669 (ltu:DI (match_dup 1)
8670 (match_dup 2)))
8671 (set (match_dup 0)
8672 (xor:DI (match_dup 0)
8673 (const_int 1)))]
8674 "")
8675
8ef30996
MM
8676(define_expand "sltu"
8677 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8678 (ltu:SI (match_dup 1)
8ef30996
MM
8679 (match_dup 2)))]
8680 ""
8681 "
8682{
bb621ad7 8683 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8684 FAIL;
8685
8686 /* set up operands from compare. */
8687 operands[1] = branch_cmp[0];
8688 operands[2] = branch_cmp[1];
8689
2bcb2ab3 8690 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8691 {
8692 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8693 DONE;
8694 }
8695
8ef30996
MM
8696 /* fall through and generate default code */
8697}")
8698
8699(define_insn "sltu_si"
8700 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8701 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8ef30996 8702 (match_operand:SI 2 "arith_operand" "dI")))]
2bcb2ab3 8703 "!TARGET_MIPS16"
8ef30996 8704 "sltu\\t%0,%1,%2"
bb621ad7 8705 [(set_attr "type" "arith")
0ff83799 8706 (set_attr "mode" "SI")])
8ef30996 8707
2bcb2ab3
GK
8708(define_insn ""
8709 [(set (match_operand:SI 0 "register_operand" "=t,t")
8710 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8711 (match_operand:SI 2 "arith_operand" "d,I")))]
8712 "TARGET_MIPS16"
8713 "sltu\\t%1,%2"
8714 [(set_attr "type" "arith")
8715 (set_attr "mode" "SI")
8716 (set_attr_alternative "length"
0ff83799 8717 [(const_int 4)
2bcb2ab3 8718 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8719 (const_int 4)
8720 (const_int 8))])])
2bcb2ab3 8721
bb621ad7
JW
8722(define_insn "sltu_di"
8723 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8724 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8725 (match_operand:DI 2 "se_arith_operand" "dI")))]
2bcb2ab3 8726 "TARGET_64BIT && !TARGET_MIPS16"
bb621ad7
JW
8727 "sltu\\t%0,%1,%2"
8728 [(set_attr "type" "arith")
0ff83799 8729 (set_attr "mode" "DI")])
bb621ad7 8730
2bcb2ab3
GK
8731(define_insn ""
8732 [(set (match_operand:DI 0 "register_operand" "=t,t")
8733 (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8734 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8735 "TARGET_64BIT && TARGET_MIPS16"
8736 "sltu\\t%1,%2"
8737 [(set_attr "type" "arith")
8738 (set_attr "mode" "DI")
8739 (set_attr_alternative "length"
0ff83799 8740 [(const_int 4)
2bcb2ab3 8741 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
0ff83799
MM
8742 (const_int 4)
8743 (const_int 8))])])
2bcb2ab3 8744
8ef30996
MM
8745(define_expand "sleu"
8746 [(set (match_operand:SI 0 "register_operand" "=d")
34b650b3 8747 (leu:SI (match_dup 1)
8ef30996
MM
8748 (match_dup 2)))]
8749 ""
8750 "
8751{
bb621ad7 8752 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8ef30996
MM
8753 FAIL;
8754
8755 /* set up operands from compare. */
8756 operands[1] = branch_cmp[0];
8757 operands[2] = branch_cmp[1];
8758
2bcb2ab3 8759 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
34b650b3
MM
8760 {
8761 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8762 DONE;
8763 }
8764
8ef30996
MM
8765 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8766 operands[2] = force_reg (SImode, operands[2]);
8767
8768 /* fall through and generate default code */
8769}")
8770
34b650b3
MM
8771(define_insn "sleu_si_const"
8772 [(set (match_operand:SI 0 "register_operand" "=d")
8773 (leu:SI (match_operand:SI 1 "register_operand" "d")
8774 (match_operand:SI 2 "small_int" "I")))]
2bcb2ab3 8775 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
34b650b3
MM
8776 "*
8777{
c5c76735 8778 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
34b650b3
MM
8779 return \"sltu\\t%0,%1,%2\";
8780}"
bb621ad7 8781 [(set_attr "type" "arith")
0ff83799 8782 (set_attr "mode" "SI")])
34b650b3 8783
2bcb2ab3
GK
8784(define_insn ""
8785 [(set (match_operand:SI 0 "register_operand" "=t")
8786 (leu:SI (match_operand:SI 1 "register_operand" "d")
8787 (match_operand:SI 2 "small_int" "I")))]
8788 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8789 "*
8790{
95936d18 8791 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
8792 return \"sltu\\t%1,%2\";
8793}"
8794 [(set_attr "type" "arith")
8795 (set_attr "mode" "SI")
8796 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
8797 (const_int 4)
8798 (const_int 8)))])
2bcb2ab3 8799
bb621ad7
JW
8800(define_insn "sleu_di_const"
8801 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152 8802 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
bb621ad7 8803 (match_operand:DI 2 "small_int" "I")))]
2bcb2ab3 8804 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
bb621ad7
JW
8805 "*
8806{
c5c76735 8807 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
bb621ad7
JW
8808 return \"sltu\\t%0,%1,%2\";
8809}"
8810 [(set_attr "type" "arith")
0ff83799 8811 (set_attr "mode" "DI")])
bb621ad7 8812
2bcb2ab3
GK
8813(define_insn ""
8814 [(set (match_operand:DI 0 "register_operand" "=t")
8815 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8816 (match_operand:DI 2 "small_int" "I")))]
8817 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8818 "*
8819{
95936d18 8820 operands[2] = GEN_INT (INTVAL (operands[2])+1);
2bcb2ab3
GK
8821 return \"sltu\\t%1,%2\";
8822}"
8823 [(set_attr "type" "arith")
8824 (set_attr "mode" "DI")
8825 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
0ff83799
MM
8826 (const_int 4)
8827 (const_int 8)))])
2bcb2ab3 8828
34b650b3
MM
8829(define_insn "sleu_si_reg"
8830 [(set (match_operand:SI 0 "register_operand" "=d")
8831 (leu:SI (match_operand:SI 1 "register_operand" "d")
8832 (match_operand:SI 2 "register_operand" "d")))]
2bcb2ab3 8833 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
34b650b3 8834 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
bb621ad7 8835 [(set_attr "type" "arith")
34b650b3 8836 (set_attr "mode" "SI")
0ff83799 8837 (set_attr "length" "8")])
8ef30996
MM
8838
8839(define_split
8840 [(set (match_operand:SI 0 "register_operand" "")
34b650b3 8841 (leu:SI (match_operand:SI 1 "register_operand" "")
8ef30996 8842 (match_operand:SI 2 "register_operand" "")))]
2bcb2ab3 8843 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8ef30996 8844 [(set (match_dup 0)
34b650b3 8845 (ltu:SI (match_dup 2)
8ef30996
MM
8846 (match_dup 1)))
8847 (set (match_dup 0)
8848 (xor:SI (match_dup 0)
8849 (const_int 1)))]
8850 "")
8851
bb621ad7
JW
8852(define_insn "sleu_di_reg"
8853 [(set (match_operand:DI 0 "register_operand" "=d")
1908a152
ILT
8854 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8855 (match_operand:DI 2 "se_register_operand" "d")))]
2bcb2ab3 8856 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
bb621ad7
JW
8857 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8858 [(set_attr "type" "arith")
8859 (set_attr "mode" "DI")
0ff83799 8860 (set_attr "length" "8")])
bb621ad7
JW
8861
8862(define_split
8863 [(set (match_operand:DI 0 "register_operand" "")
1908a152
ILT
8864 (leu:DI (match_operand:DI 1 "se_register_operand" "")
8865 (match_operand:DI 2 "se_register_operand" "")))]
2bcb2ab3
GK
8866 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8867 && !TARGET_MIPS16"
bb621ad7
JW
8868 [(set (match_dup 0)
8869 (ltu:DI (match_dup 2)
8870 (match_dup 1)))
8871 (set (match_dup 0)
8872 (xor:DI (match_dup 0)
8873 (const_int 1)))]
8874 "")
8875
34b650b3
MM
8876\f
8877;;
8878;; ....................
8879;;
8880;; FLOATING POINT COMPARISONS
8881;;
8882;; ....................
8883
8884(define_insn "seq_df"
b8eb88d0
ILT
8885 [(set (match_operand:CC 0 "register_operand" "=z")
8886 (eq:CC (match_operand:DF 1 "register_operand" "f")
8887 (match_operand:DF 2 "register_operand" "f")))]
46299de9 8888 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
8889 "*
8890{
b8eb88d0 8891 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
8892}"
8893 [(set_attr "type" "fcmp")
0ff83799 8894 (set_attr "mode" "FPSW")])
34b650b3
MM
8895
8896(define_insn "slt_df"
b8eb88d0
ILT
8897 [(set (match_operand:CC 0 "register_operand" "=z")
8898 (lt:CC (match_operand:DF 1 "register_operand" "f")
8899 (match_operand:DF 2 "register_operand" "f")))]
46299de9 8900 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
8901 "*
8902{
b8eb88d0 8903 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
8904}"
8905 [(set_attr "type" "fcmp")
0ff83799 8906 (set_attr "mode" "FPSW")])
34b650b3
MM
8907
8908(define_insn "sle_df"
b8eb88d0
ILT
8909 [(set (match_operand:CC 0 "register_operand" "=z")
8910 (le:CC (match_operand:DF 1 "register_operand" "f")
8911 (match_operand:DF 2 "register_operand" "f")))]
46299de9 8912 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
8913 "*
8914{
b8eb88d0 8915 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
8916}"
8917 [(set_attr "type" "fcmp")
0ff83799 8918 (set_attr "mode" "FPSW")])
34b650b3
MM
8919
8920(define_insn "sgt_df"
b8eb88d0
ILT
8921 [(set (match_operand:CC 0 "register_operand" "=z")
8922 (gt:CC (match_operand:DF 1 "register_operand" "f")
8923 (match_operand:DF 2 "register_operand" "f")))]
46299de9 8924 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
8925 "*
8926{
b8eb88d0 8927 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
8928}"
8929 [(set_attr "type" "fcmp")
0ff83799 8930 (set_attr "mode" "FPSW")])
34b650b3
MM
8931
8932(define_insn "sge_df"
b8eb88d0
ILT
8933 [(set (match_operand:CC 0 "register_operand" "=z")
8934 (ge:CC (match_operand:DF 1 "register_operand" "f")
8935 (match_operand:DF 2 "register_operand" "f")))]
46299de9 8936 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
34b650b3
MM
8937 "*
8938{
b8eb88d0 8939 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
8940}"
8941 [(set_attr "type" "fcmp")
0ff83799 8942 (set_attr "mode" "FPSW")])
34b650b3
MM
8943
8944(define_insn "seq_sf"
b8eb88d0
ILT
8945 [(set (match_operand:CC 0 "register_operand" "=z")
8946 (eq:CC (match_operand:SF 1 "register_operand" "f")
8947 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 8948 "TARGET_HARD_FLOAT"
34b650b3
MM
8949 "*
8950{
b8eb88d0 8951 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
8952}"
8953 [(set_attr "type" "fcmp")
0ff83799 8954 (set_attr "mode" "FPSW")])
34b650b3
MM
8955
8956(define_insn "slt_sf"
b8eb88d0
ILT
8957 [(set (match_operand:CC 0 "register_operand" "=z")
8958 (lt:CC (match_operand:SF 1 "register_operand" "f")
8959 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 8960 "TARGET_HARD_FLOAT"
34b650b3
MM
8961 "*
8962{
b8eb88d0 8963 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
8964}"
8965 [(set_attr "type" "fcmp")
0ff83799 8966 (set_attr "mode" "FPSW")])
34b650b3
MM
8967
8968(define_insn "sle_sf"
b8eb88d0
ILT
8969 [(set (match_operand:CC 0 "register_operand" "=z")
8970 (le:CC (match_operand:SF 1 "register_operand" "f")
8971 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 8972 "TARGET_HARD_FLOAT"
34b650b3
MM
8973 "*
8974{
b8eb88d0 8975 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
34b650b3
MM
8976}"
8977 [(set_attr "type" "fcmp")
0ff83799 8978 (set_attr "mode" "FPSW")])
34b650b3
MM
8979
8980(define_insn "sgt_sf"
b8eb88d0
ILT
8981 [(set (match_operand:CC 0 "register_operand" "=z")
8982 (gt:CC (match_operand:SF 1 "register_operand" "f")
8983 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 8984 "TARGET_HARD_FLOAT"
34b650b3
MM
8985 "*
8986{
b8eb88d0 8987 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
8988}"
8989 [(set_attr "type" "fcmp")
0ff83799 8990 (set_attr "mode" "FPSW")])
34b650b3
MM
8991
8992(define_insn "sge_sf"
b8eb88d0
ILT
8993 [(set (match_operand:CC 0 "register_operand" "=z")
8994 (ge:CC (match_operand:SF 1 "register_operand" "f")
8995 (match_operand:SF 2 "register_operand" "f")))]
bb621ad7 8996 "TARGET_HARD_FLOAT"
34b650b3
MM
8997 "*
8998{
b8eb88d0 8999 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
34b650b3
MM
9000}"
9001 [(set_attr "type" "fcmp")
0ff83799 9002 (set_attr "mode" "FPSW")])
34b650b3 9003
8ef30996
MM
9004\f
9005;;
9006;; ....................
9007;;
9008;; UNCONDITIONAL BRANCHES
9009;;
9010;; ....................
9011
9012;; Unconditional branches.
9013
9014(define_insn "jump"
9015 [(set (pc)
9016 (label_ref (match_operand 0 "" "")))]
2bcb2ab3 9017 "!TARGET_MIPS16"
8ef30996
MM
9018 "*
9019{
9020 if (GET_CODE (operands[0]) == REG)
9021 return \"%*j\\t%0\";
e19ff60f
JW
9022 /* ??? I don't know why this is necessary. This works around an
9023 assembler problem that appears when a label is defined, then referenced
9024 in a switch table, then used in a `j' instruction. */
a53f72db 9025 else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
e19ff60f
JW
9026 return \"%*b\\t%l0\";
9027 else
8ef30996
MM
9028 return \"%*j\\t%l0\";
9029}"
9030 [(set_attr "type" "jump")
0ff83799 9031 (set_attr "mode" "none")])
8ef30996 9032
2bcb2ab3
GK
9033;; We need a different insn for the mips16, because a mips16 branch
9034;; does not have a delay slot.
9035
9036(define_insn ""
9037 [(set (pc)
9038 (label_ref (match_operand 0 "" "")))]
9039 "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9040 "b\\t%l0"
9041 [(set_attr "type" "branch")
9042 (set_attr "mode" "none")
0ff83799 9043 (set_attr "length" "8")])
2bcb2ab3 9044
bb621ad7
JW
9045(define_expand "indirect_jump"
9046 [(set (pc) (match_operand 0 "register_operand" "d"))]
8ef30996 9047 ""
bb621ad7
JW
9048 "
9049{
9050 rtx dest;
9051
9052 if (operands[0]) /* eliminate unused code warnings */
9053 {
9054 dest = operands[0];
9055 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9056 operands[0] = copy_to_mode_reg (Pmode, dest);
9057
1eeed24e 9058 if (!(Pmode == DImode))
bb621ad7
JW
9059 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9060 else
9061 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9062
9063 DONE;
9064 }
9065}")
9066
9067(define_insn "indirect_jump_internal1"
9068 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
1eeed24e 9069 "!(Pmode == DImode)"
bb621ad7
JW
9070 "%*j\\t%0"
9071 [(set_attr "type" "jump")
0ff83799 9072 (set_attr "mode" "none")])
bb621ad7
JW
9073
9074(define_insn "indirect_jump_internal2"
1908a152 9075 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
1eeed24e 9076 "Pmode == DImode"
8ef30996
MM
9077 "%*j\\t%0"
9078 [(set_attr "type" "jump")
0ff83799 9079 (set_attr "mode" "none")])
8ef30996 9080
bb621ad7 9081(define_expand "tablejump"
8ef30996 9082 [(set (pc)
bb621ad7 9083 (match_operand 0 "register_operand" "d"))
8ef30996
MM
9084 (use (label_ref (match_operand 1 "" "")))]
9085 ""
bb621ad7
JW
9086 "
9087{
bb621ad7
JW
9088 if (operands[0]) /* eliminate unused code warnings */
9089 {
2bcb2ab3
GK
9090 if (TARGET_MIPS16)
9091 {
9092 if (GET_MODE (operands[0]) != HImode)
9093 abort ();
1eeed24e 9094 if (!(Pmode == DImode))
bf4f78ee 9095 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
2bcb2ab3 9096 else
bf4f78ee 9097 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
2bcb2ab3
GK
9098 DONE;
9099 }
9100
bb621ad7
JW
9101 if (GET_MODE (operands[0]) != Pmode)
9102 abort ();
9103
9fa0af71
JW
9104 if (! flag_pic)
9105 {
1eeed24e 9106 if (!(Pmode == DImode))
9fa0af71
JW
9107 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9108 else
9109 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9110 }
bb621ad7 9111 else
9fa0af71 9112 {
1eeed24e 9113 if (!(Pmode == DImode))
9fa0af71
JW
9114 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9115 else
9116 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9117 }
bb621ad7
JW
9118
9119 DONE;
9120 }
9121}")
9122
9123(define_insn "tablejump_internal1"
9124 [(set (pc)
9125 (match_operand:SI 0 "register_operand" "d"))
9126 (use (label_ref (match_operand 1 "" "")))]
1eeed24e 9127 "!(Pmode == DImode)"
9fa0af71 9128 "%*j\\t%0"
bb621ad7 9129 [(set_attr "type" "jump")
0ff83799 9130 (set_attr "mode" "none")])
bb621ad7
JW
9131
9132(define_insn "tablejump_internal2"
9133 [(set (pc)
1908a152 9134 (match_operand:DI 0 "se_register_operand" "d"))
bb621ad7 9135 (use (label_ref (match_operand 1 "" "")))]
1eeed24e 9136 "Pmode == DImode"
9fa0af71
JW
9137 "%*j\\t%0"
9138 [(set_attr "type" "jump")
0ff83799 9139 (set_attr "mode" "none")])
9fa0af71
JW
9140
9141(define_expand "tablejump_internal3"
5924eecf
KR
9142 [(parallel [(set (pc)
9143 (plus:SI (match_operand:SI 0 "register_operand" "d")
cf45bb06 9144 (label_ref:SI (match_operand 1 "" ""))))
5924eecf 9145 (use (label_ref:SI (match_dup 1)))])]
9fa0af71
JW
9146 ""
9147 "")
9148
2bcb2ab3
GK
9149(define_expand "tablejump_mips161"
9150 [(set (pc) (plus:SI (sign_extend:SI
9151 (match_operand:HI 0 "register_operand" "d"))
cf45bb06 9152 (label_ref:SI (match_operand 1 "" ""))))]
1eeed24e 9153 "TARGET_MIPS16 && !(Pmode == DImode)"
2bcb2ab3
GK
9154 "
9155{
9156 if (operands[0]) /* eliminate unused code warnings. */
9157 {
9158 rtx t1, t2, t3;
9159
9160 t1 = gen_reg_rtx (SImode);
9161 t2 = gen_reg_rtx (SImode);
9162 t3 = gen_reg_rtx (SImode);
9163 emit_insn (gen_extendhisi2 (t1, operands[0]));
9164 emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9165 emit_insn (gen_addsi3 (t3, t1, t2));
bf4f78ee 9166 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
2bcb2ab3
GK
9167 DONE;
9168 }
9169}")
9170
9171(define_expand "tablejump_mips162"
9172 [(set (pc) (plus:DI (sign_extend:DI
9173 (match_operand:HI 0 "register_operand" "d"))
cf45bb06 9174 (label_ref:DI (match_operand 1 "" ""))))]
1eeed24e 9175 "TARGET_MIPS16 && Pmode == DImode"
2bcb2ab3
GK
9176 "
9177{
9178 if (operands[0]) /* eliminate unused code warnings. */
9179 {
9180 rtx t1, t2, t3;
9181
9182 t1 = gen_reg_rtx (DImode);
9183 t2 = gen_reg_rtx (DImode);
9184 t3 = gen_reg_rtx (DImode);
9185 emit_insn (gen_extendhidi2 (t1, operands[0]));
9186 emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9187 emit_insn (gen_adddi3 (t3, t1, t2));
bf4f78ee 9188 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
2bcb2ab3
GK
9189 DONE;
9190 }
9191}")
9192
9fa0af71 9193;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
05714a4f
KR
9194;;; it is not valid. ??? With the USE, the condition tests may not be required
9195;;; any longer.
9fa0af71
JW
9196
9197;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
9198;;; We just use the conservative number here.
9199
9200(define_insn ""
9201 [(set (pc)
9202 (plus:SI (match_operand:SI 0 "register_operand" "d")
cf45bb06 9203 (label_ref:SI (match_operand 1 "" ""))))
5924eecf 9204 (use (label_ref:SI (match_dup 1)))]
1eeed24e 9205 "!(Pmode == DImode) && next_active_insn (insn) != 0
9fa0af71
JW
9206 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9207 && PREV_INSN (next_active_insn (insn)) == operands[1]"
5a5b76a2
JW
9208 "*
9209{
9fa0af71 9210 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
a53f72db 9211 if (mips_abi == ABI_32 || mips_abi == ABI_O64)
e19ff60f 9212 output_asm_insn (\".cpadd\\t%0\", operands);
5a5b76a2
JW
9213 return \"%*j\\t%0\";
9214}"
8ef30996
MM
9215 [(set_attr "type" "jump")
9216 (set_attr "mode" "none")
0ff83799 9217 (set_attr "length" "8")])
9fa0af71
JW
9218
9219(define_expand "tablejump_internal4"
5924eecf
KR
9220 [(parallel [(set (pc)
9221 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
cf45bb06 9222 (label_ref:DI (match_operand 1 "" ""))))
5924eecf 9223 (use (label_ref:DI (match_dup 1)))])]
9fa0af71
JW
9224 ""
9225 "")
9226
9227;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
05714a4f
KR
9228;;; it is not valid. ??? With the USE, the condition tests may not be required
9229;;; any longer.
9fa0af71
JW
9230
9231(define_insn ""
9232 [(set (pc)
1908a152 9233 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
cf45bb06 9234 (label_ref:DI (match_operand 1 "" ""))))
5924eecf 9235 (use (label_ref:DI (match_dup 1)))]
1eeed24e 9236 "Pmode == DImode && next_active_insn (insn) != 0
9fa0af71
JW
9237 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9238 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9239 "%*j\\t%0"
9240 [(set_attr "type" "jump")
0ff83799 9241 (set_attr "mode" "none")])
8ef30996 9242
e0bfcea5
ILT
9243;; Implement a switch statement when generating embedded PIC code.
9244;; Switches are implemented by `tablejump' when not using -membedded-pic.
9245
9246(define_expand "casesi"
9247 [(set (match_dup 5)
9248 (minus:SI (match_operand:SI 0 "register_operand" "d")
9249 (match_operand:SI 1 "arith_operand" "dI")))
9250 (set (cc0)
9251 (compare:CC (match_dup 5)
9252 (match_operand:SI 2 "arith_operand" "")))
9253 (set (pc)
9254 (if_then_else (gtu (cc0)
9255 (const_int 0))
9256 (label_ref (match_operand 4 "" ""))
9257 (pc)))
9258 (parallel
9259 [(set (pc)
9260 (mem:SI (plus:SI (mult:SI (match_dup 5)
9261 (const_int 4))
9262 (label_ref (match_operand 3 "" "")))))
9263 (clobber (match_scratch:SI 6 ""))
9264 (clobber (reg:SI 31))])]
9265 "TARGET_EMBEDDED_PIC"
9266 "
9267{
e0bfcea5
ILT
9268 if (operands[0])
9269 {
9270 rtx reg = gen_reg_rtx (SImode);
9271
e0bfcea5
ILT
9272 /* If the index is too large, go to the default label. */
9273 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9274 emit_insn (gen_cmpsi (reg, operands[2]));
9275 emit_insn (gen_bgtu (operands[4]));
9276
9277 /* Do the PIC jump. */
9c9e7632
GK
9278 if (Pmode != DImode)
9279 emit_jump_insn (gen_casesi_internal (reg, operands[3],
9280 gen_reg_rtx (SImode)));
9281 else
9282 emit_jump_insn (gen_casesi_internal_di (reg, operands[3],
9283 gen_reg_rtx (DImode)));
e0bfcea5
ILT
9284
9285 DONE;
9286 }
9287}")
9288
9289;; An embedded PIC switch statement looks like this:
9290;; bal $LS1
810c1b83 9291;; sll $reg,$index,2
e0bfcea5
ILT
9292;; $LS1:
9293;; addu $reg,$reg,$31
9294;; lw $reg,$L1-$LS1($reg)
9295;; addu $reg,$reg,$31
9296;; j $reg
9297;; $L1:
9298;; .word case1-$LS1
9299;; .word case2-$LS1
9300;; ...
9301
9302(define_insn "casesi_internal"
9303 [(set (pc)
9304 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9305 (const_int 4))
9306 (label_ref (match_operand 1 "" "")))))
0e7e9155 9307 (clobber (match_operand:SI 2 "register_operand" "=d"))
e0bfcea5
ILT
9308 (clobber (reg:SI 31))]
9309 "TARGET_EMBEDDED_PIC"
810c1b83
RH
9310 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9311lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\;j\\t%2"
e0bfcea5
ILT
9312 [(set_attr "type" "jump")
9313 (set_attr "mode" "none")
0ff83799 9314 (set_attr "length" "24")])
e0bfcea5 9315
9c9e7632
GK
9316(define_insn "casesi_internal_di"
9317 [(set (pc)
9318 (mem:DI (plus:DI (sign_extend:DI
9319 (mult:SI (match_operand:SI 0 "register_operand" "d")
58dbe05f 9320 (const_int 4)))
9c9e7632
GK
9321 (label_ref (match_operand 1 "" "")))))
9322 (clobber (match_operand:DI 2 "register_operand" "=d"))
9323 (clobber (reg:DI 31))]
9324 "TARGET_EMBEDDED_PIC"
9325 "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
9326ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\;j\\t%2"
9327 [(set_attr "type" "jump")
9328 (set_attr "mode" "none")
9329 (set_attr "length" "24")])
9330
6fd1c67b
RH
9331;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9332;; possible to either pull it off the stack (in the o32 case) or recalculate
9333;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9334;; this is easy.
9335
9336(define_expand "builtin_setjmp_setup"
9337 [(unspec [(match_operand 0 "register_operand" "r")] 20)]
9338 "TARGET_ABICALLS"
d5d1738a
JW
9339 "
9340{
1eeed24e 9341 if (Pmode == DImode)
6fd1c67b
RH
9342 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9343 else
9344 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9345 DONE;
d5d1738a 9346}")
c85f7c16 9347
6fd1c67b
RH
9348(define_expand "builtin_setjmp_setup_32"
9349 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9350 (const_int 12)))
9351 (reg:SI 28))]
1eeed24e 9352 "TARGET_ABICALLS && ! (Pmode == DImode)"
6fd1c67b 9353 "")
c85f7c16 9354
6fd1c67b
RH
9355(define_expand "builtin_setjmp_setup_64"
9356 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9357 (const_int 24)))
9358 (reg:DI 28))]
1eeed24e 9359 "TARGET_ABICALLS && Pmode == DImode"
6fd1c67b
RH
9360 "")
9361
9362;; For o32/n32/n64, we need to arrange for longjmp to put the
9363;; target address in t9 so that we can use it for loading $gp.
9364
9365(define_expand "builtin_longjmp"
9366 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
9367 "TARGET_ABICALLS"
c85f7c16
JL
9368 "
9369{
6fd1c67b 9370 /* The elements of the buffer are, in order: */
1eeed24e 9371 int W = (Pmode == DImode ? 8 : 4);
6fd1c67b
RH
9372 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9373 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9374 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9375 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9376 rtx pv = gen_rtx_REG (Pmode, 25);
9377 rtx gp = gen_rtx_REG (Pmode, 28);
9378
9379 /* This bit is the same as expand_builtin_longjmp. */
9380 emit_move_insn (hard_frame_pointer_rtx, fp);
9381 emit_move_insn (pv, lab);
9382 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9383 emit_move_insn (gp, gpv);
9384 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9385 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9386 emit_insn (gen_rtx_USE (VOIDmode, gp));
9387 emit_indirect_jump (pv);
9388 DONE;
c85f7c16 9389}")
0fb5ac6f
MM
9390\f
9391;;
9392;; ....................
9393;;
9394;; Function prologue/epilogue
9395;;
9396;; ....................
9397;;
9398
9399(define_expand "prologue"
9400 [(const_int 1)]
9401 ""
9402 "
9403{
9404 if (mips_isa >= 0) /* avoid unused code warnings */
9405 {
9406 mips_expand_prologue ();
9407 DONE;
9408 }
9409}")
9410
d8d5b1e1
MM
9411;; Block any insns from being moved before this point, since the
9412;; profiling call to mcount can use various registers that aren't
9413;; saved or used to pass arguments.
9414
9415(define_insn "blockage"
9416 [(unspec_volatile [(const_int 0)] 0)]
9417 ""
9418 ""
9419 [(set_attr "type" "unknown")
9420 (set_attr "mode" "none")
9421 (set_attr "length" "0")])
9422
1f2d8f51
JL
9423(define_expand "epilogue"
9424 [(const_int 2)]
9425 ""
9426 "
9427{
9428 if (mips_isa >= 0) /* avoid unused code warnings */
9429 {
9430 mips_expand_epilogue ();
9431 DONE;
9432 }
9433}")
0fb5ac6f 9434
1f2d8f51
JL
9435;; Trivial return. Make it look like a normal return insn as that
9436;; allows jump optimizations to work better .
9437(define_insn "return"
9438 [(return)]
9439 "mips_can_use_return_insn ()"
8fa4e1b4 9440 "%*j\\t$31"
1f2d8f51 9441 [(set_attr "type" "jump")
0ff83799 9442 (set_attr "mode" "none")])
1f2d8f51
JL
9443
9444;; Normal return.
0e7e9155 9445
1f2d8f51 9446(define_insn "return_internal"
0e7e9155 9447 [(use (match_operand 0 "pmode_register_operand" ""))
1f2d8f51
JL
9448 (return)]
9449 ""
2bcb2ab3
GK
9450 "*
9451{
9452 return \"%*j\\t%0\";
9453}"
1f2d8f51 9454 [(set_attr "type" "jump")
0ff83799 9455 (set_attr "mode" "none")])
1f2d8f51 9456
92544bdf
ILT
9457;; When generating embedded PIC code we need to get the address of the
9458;; current function. This specialized instruction does just that.
9459
9460(define_insn "get_fnaddr"
0d3b5987 9461 [(set (match_operand 0 "register_operand" "=d")
92544bdf
ILT
9462 (unspec [(match_operand 1 "" "")] 1))
9463 (clobber (reg:SI 31))]
9464 "TARGET_EMBEDDED_PIC
9465 && GET_CODE (operands[1]) == SYMBOL_REF"
9466 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9467 [(set_attr "type" "call")
9468 (set_attr "mode" "none")
0ff83799 9469 (set_attr "length" "16")])
92544bdf 9470
8ef30996
MM
9471\f
9472;;
9473;; ....................
9474;;
9475;; FUNCTION CALLS
9476;;
9477;; ....................
9478
9479;; calls.c now passes a third argument, make saber happy
9480
9481(define_expand "call"
af4a697f 9482 [(parallel [(call (match_operand 0 "memory_operand" "m")
8ef30996 9483 (match_operand 1 "" "i"))
3f1f8d8c
MM
9484 (clobber (reg:SI 31))
9485 (use (match_operand 2 "" "")) ;; next_arg_reg
9486 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
8ef30996
MM
9487 ""
9488 "
9489{
9490 rtx addr;
9491
3f1f8d8c
MM
9492 if (operands[0]) /* eliminate unused code warnings */
9493 {
9494 addr = XEXP (operands[0], 0);
322dce45 9495 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
aa4e54c4 9496 || ! call_insn_operand (addr, VOIDmode))
322dce45 9497 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
3f1f8d8c
MM
9498
9499 /* In order to pass small structures by value in registers
9500 compatibly with the MIPS compiler, we need to shift the value
9501 into the high part of the register. Function_arg has encoded
9502 a PARALLEL rtx, holding a vector of adjustments to be made
9503 as the next_arg_reg variable, so we split up the insns,
9504 and emit them separately. */
9505
9506 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9507 {
9508 rtvec adjust = XVEC (operands[2], 0);
9509 int num = GET_NUM_ELEM (adjust);
9510 int i;
9511
9512 for (i = 0; i < num; i++)
9513 emit_insn (RTVEC_ELT (adjust, i));
9514 }
8ef30996 9515
2bcb2ab3
GK
9516 if (TARGET_MIPS16
9517 && mips16_hard_float
9518 && operands[2] != 0
9519 && (int) GET_MODE (operands[2]) != 0)
9520 {
9521 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9522 (int) GET_MODE (operands[2])))
9523 DONE;
9524 }
9525
aa4e54c4 9526 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
c5c76735
JL
9527 gen_rtx_REG (SImode,
9528 GP_REG_FIRST + 31)));
3f1f8d8c
MM
9529 DONE;
9530 }
8ef30996
MM
9531}")
9532
aa4e54c4
JW
9533(define_expand "call_internal0"
9534 [(parallel [(call (match_operand 0 "" "")
9535 (match_operand 1 "" ""))
9536 (clobber (match_operand:SI 2 "" ""))])]
9537 ""
9538 "")
9539
2bcb2ab3
GK
9540;; We need to recognize reg:SI 31 specially for the mips16, because we
9541;; don't have a constraint letter for it.
9542
9543(define_insn ""
9544 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9545 (match_operand 1 "" "i"))
9546 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9547 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9548 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9549 "%*jal\\t%0"
9550 [(set_attr "type" "call")
9551 (set_attr "mode" "none")
0ff83799 9552 (set_attr "length" "8")])
2bcb2ab3 9553
d1399bd0 9554(define_insn "call_internal1"
aa4e54c4 9555 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
8ef30996
MM
9556 (match_operand 1 "" "i"))
9557 (clobber (match_operand:SI 2 "register_operand" "=d"))]
84a92af4 9558 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
8ef30996
MM
9559 "*
9560{
aa4e54c4 9561 register rtx target = operands[0];
8ef30996
MM
9562
9563 if (GET_CODE (target) == SYMBOL_REF)
9564 return \"%*jal\\t%0\";
2bba3a75 9565 else if (GET_CODE (target) == CONST_INT)
5aae9091 9566 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
8ef30996 9567 else
5aae9091 9568 return \"%*jal\\t%2,%0\";
8ef30996
MM
9569}"
9570 [(set_attr "type" "call")
0ff83799 9571 (set_attr "mode" "none")])
8ef30996 9572
d1399bd0 9573(define_insn "call_internal2"
aa4e54c4 9574 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
84a92af4
JW
9575 (match_operand 1 "" "i"))
9576 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9577 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9578 "*
9579{
aa4e54c4 9580 register rtx target = operands[0];
84a92af4
JW
9581
9582 if (GET_CODE (target) == SYMBOL_REF)
84a92af4 9583 {
5aae9091
JW
9584 if (GET_MODE (target) == SImode)
9585 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
84a92af4 9586 else
5aae9091 9587 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
84a92af4 9588 }
5aae9091
JW
9589 else if (GET_CODE (target) == CONST_INT)
9590 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9591 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9592 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9593 else
9594 return \"jal\\t%2,%0\";
84a92af4
JW
9595}"
9596 [(set_attr "type" "call")
9597 (set_attr "mode" "none")
0ff83799 9598 (set_attr "length" "8")])
84a92af4 9599
bb621ad7 9600(define_insn "call_internal3a"
d1399bd0
MM
9601 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9602 (match_operand 1 "" "i"))
9603 (clobber (match_operand:SI 2 "register_operand" "=d"))]
8da665d5
SC
9604 "!TARGET_MIPS16
9605 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
bb621ad7
JW
9606 "%*jal\\t%2,%0"
9607 [(set_attr "type" "call")
0ff83799 9608 (set_attr "mode" "none")])
bb621ad7
JW
9609
9610(define_insn "call_internal3b"
1908a152 9611 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
bb621ad7
JW
9612 (match_operand 1 "" "i"))
9613 (clobber (match_operand:SI 2 "register_operand" "=d"))]
8da665d5
SC
9614 "!TARGET_MIPS16
9615 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9616 "%*jal\\t%2,%0"
9617 [(set_attr "type" "call")
9618 (set_attr "mode" "none")
9619 (set_attr "length" "1")])
9620
9621(define_insn "call_internal3c"
9622 [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
9623 (match_operand 1 "" "i"))
9624 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9625 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9626 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
d1399bd0
MM
9627 "%*jal\\t%2,%0"
9628 [(set_attr "type" "call")
0ff83799 9629 (set_attr "mode" "none")])
d1399bd0 9630
bb621ad7 9631(define_insn "call_internal4a"
84a92af4
JW
9632 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9633 (match_operand 1 "" "i"))
9634 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1eeed24e 9635 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
84a92af4
JW
9636 "*
9637{
9638 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9639 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9640 else
9641 return \"jal\\t%2,%0\";
9642}"
9643 [(set_attr "type" "call")
9644 (set_attr "mode" "none")
0ff83799 9645 (set_attr "length" "8")])
84a92af4 9646
bb621ad7 9647(define_insn "call_internal4b"
1908a152 9648 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
bb621ad7
JW
9649 (match_operand 1 "" "i"))
9650 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1eeed24e 9651 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
bb621ad7
JW
9652 "*
9653{
9654 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9655 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9656 else
9657 return \"jal\\t%2,%0\";
9658}"
9659 [(set_attr "type" "call")
9660 (set_attr "mode" "none")
0ff83799 9661 (set_attr "length" "8")])
d1399bd0 9662
8ef30996
MM
9663;; calls.c now passes a fourth argument, make saber happy
9664
9665(define_expand "call_value"
9666 [(parallel [(set (match_operand 0 "register_operand" "=df")
af4a697f 9667 (call (match_operand 1 "memory_operand" "m")
8ef30996 9668 (match_operand 2 "" "i")))
3f1f8d8c
MM
9669 (clobber (reg:SI 31))
9670 (use (match_operand 3 "" ""))])] ;; next_arg_reg
8ef30996
MM
9671 ""
9672 "
9673{
9674 rtx addr;
9675
3f1f8d8c
MM
9676 if (operands[0]) /* eliminate unused code warning */
9677 {
9678 addr = XEXP (operands[1], 0);
322dce45 9679 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
aa4e54c4 9680 || ! call_insn_operand (addr, VOIDmode))
322dce45 9681 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
3f1f8d8c
MM
9682
9683 /* In order to pass small structures by value in registers
9684 compatibly with the MIPS compiler, we need to shift the value
9685 into the high part of the register. Function_arg has encoded
9686 a PARALLEL rtx, holding a vector of adjustments to be made
9687 as the next_arg_reg variable, so we split up the insns,
9688 and emit them separately. */
9689
9690 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9691 {
9692 rtvec adjust = XVEC (operands[3], 0);
9693 int num = GET_NUM_ELEM (adjust);
9694 int i;
9695
9696 for (i = 0; i < num; i++)
9697 emit_insn (RTVEC_ELT (adjust, i));
9698 }
9699
2bcb2ab3
GK
9700 if (TARGET_MIPS16
9701 && mips16_hard_float
9702 && ((operands[3] != 0
9703 && (int) GET_MODE (operands[3]) != 0)
9704 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9705 {
9706 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9707 (operands[3] == 0 ? 0
9708 : (int) GET_MODE (operands[3]))))
9709 DONE;
9710 }
9711
bd16a708
JW
9712 /* Handle Irix6 function calls that have multiple non-contiguous
9713 results. */
f7a61b83 9714 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
bd16a708 9715 {
aa4e54c4 9716 emit_call_insn (gen_call_value_multiple_internal0
bd16a708
JW
9717 (XEXP (XVECEXP (operands[0], 0, 0), 0),
9718 operands[1], operands[2],
9719 XEXP (XVECEXP (operands[0], 0, 1), 0),
c5c76735 9720 gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
bd16a708
JW
9721 DONE;
9722 }
9723
f7a61b83
JW
9724 /* We have a call returning a DImode structure in an FP reg.
9725 Strip off the now unnecessary PARALLEL. */
9726 if (GET_CODE (operands[0]) == PARALLEL)
9727 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9728
aa4e54c4 9729 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
c5c76735
JL
9730 gen_rtx_REG (SImode,
9731 GP_REG_FIRST + 31)));
3f1f8d8c
MM
9732
9733 DONE;
9734 }
8ef30996
MM
9735}")
9736
aa4e54c4
JW
9737(define_expand "call_value_internal0"
9738 [(parallel [(set (match_operand 0 "" "")
9739 (call (match_operand 1 "" "")
9740 (match_operand 2 "" "")))
9741 (clobber (match_operand:SI 3 "" ""))])]
9742 ""
9743 "")
9744
2bcb2ab3
GK
9745;; Recognize $31 specially on the mips16, because we don't have a
9746;; constraint letter for it.
9747
9748(define_insn ""
9749 [(set (match_operand 0 "register_operand" "=d")
9750 (call (mem (match_operand 1 "call_insn_operand" "ei"))
9751 (match_operand 2 "" "i")))
9752 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9753 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9754 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9755 "%*jal\\t%1"
9756 [(set_attr "type" "call")
9757 (set_attr "mode" "none")
0ff83799 9758 (set_attr "length" "8")])
2bcb2ab3 9759
d1399bd0 9760(define_insn "call_value_internal1"
8ef30996 9761 [(set (match_operand 0 "register_operand" "=df")
aa4e54c4 9762 (call (mem (match_operand 1 "call_insn_operand" "ri"))
8ef30996
MM
9763 (match_operand 2 "" "i")))
9764 (clobber (match_operand:SI 3 "register_operand" "=d"))]
84a92af4 9765 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
8ef30996
MM
9766 "*
9767{
aa4e54c4 9768 register rtx target = operands[1];
8ef30996
MM
9769
9770 if (GET_CODE (target) == SYMBOL_REF)
9771 return \"%*jal\\t%1\";
2bba3a75 9772 else if (GET_CODE (target) == CONST_INT)
5aae9091 9773 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
8ef30996 9774 else
5aae9091 9775 return \"%*jal\\t%3,%1\";
8ef30996
MM
9776}"
9777 [(set_attr "type" "call")
0ff83799 9778 (set_attr "mode" "none")])
8ef30996 9779
d1399bd0 9780(define_insn "call_value_internal2"
84a92af4 9781 [(set (match_operand 0 "register_operand" "=df")
aa4e54c4 9782 (call (mem (match_operand 1 "call_insn_operand" "ri"))
84a92af4
JW
9783 (match_operand 2 "" "i")))
9784 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9785 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9786 "*
9787{
aa4e54c4 9788 register rtx target = operands[1];
84a92af4
JW
9789
9790 if (GET_CODE (target) == SYMBOL_REF)
84a92af4 9791 {
5aae9091
JW
9792 if (GET_MODE (target) == SImode)
9793 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
84a92af4 9794 else
5aae9091 9795 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
84a92af4 9796 }
5aae9091
JW
9797 else if (GET_CODE (target) == CONST_INT)
9798 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
9799 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9800 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9801 else
9802 return \"jal\\t%3,%1\";
84a92af4
JW
9803}"
9804 [(set_attr "type" "call")
9805 (set_attr "mode" "none")
0ff83799 9806 (set_attr "length" "8")])
84a92af4 9807
bb621ad7 9808(define_insn "call_value_internal3a"
d1399bd0
MM
9809 [(set (match_operand 0 "register_operand" "=df")
9810 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9811 (match_operand 2 "" "i")))
9812 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6d4503c3
SC
9813 "!TARGET_MIPS16
9814 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
bb621ad7
JW
9815 "%*jal\\t%3,%1"
9816 [(set_attr "type" "call")
0ff83799 9817 (set_attr "mode" "none")])
bb621ad7
JW
9818
9819(define_insn "call_value_internal3b"
9820 [(set (match_operand 0 "register_operand" "=df")
1908a152 9821 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
bb621ad7
JW
9822 (match_operand 2 "" "i")))
9823 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6d4503c3
SC
9824 "!TARGET_MIPS16
9825 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9826 "%*jal\\t%3,%1"
9827 [(set_attr "type" "call")
0ff83799 9828 (set_attr "mode" "none")])
6d4503c3
SC
9829
9830(define_insn "call_value_internal3c"
9831 [(set (match_operand 0 "register_operand" "=df")
9832 (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
9833 (match_operand 2 "" "i")))
9834 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9835 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9836 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
d1399bd0
MM
9837 "%*jal\\t%3,%1"
9838 [(set_attr "type" "call")
0ff83799 9839 (set_attr "mode" "none")])
d1399bd0 9840
bb621ad7 9841(define_insn "call_value_internal4a"
84a92af4
JW
9842 [(set (match_operand 0 "register_operand" "=df")
9843 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9844 (match_operand 2 "" "i")))
9845 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1eeed24e 9846 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
bb621ad7
JW
9847 "*
9848{
9849 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9850 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9851 else
9852 return \"jal\\t%3,%1\";
9853}"
9854 [(set_attr "type" "call")
9855 (set_attr "mode" "none")
0ff83799 9856 (set_attr "length" "8")])
bb621ad7
JW
9857
9858(define_insn "call_value_internal4b"
9859 [(set (match_operand 0 "register_operand" "=df")
1908a152 9860 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
bb621ad7
JW
9861 (match_operand 2 "" "i")))
9862 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1eeed24e 9863 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
84a92af4
JW
9864 "*
9865{
9866 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9867 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9868 else
9869 return \"jal\\t%3,%1\";
9870}"
9871 [(set_attr "type" "call")
9872 (set_attr "mode" "none")
0ff83799 9873 (set_attr "length" "8")])
84a92af4 9874
a5262009 9875(define_expand "call_value_multiple_internal0"
aa4e54c4
JW
9876 [(parallel [(set (match_operand 0 "" "")
9877 (call (match_operand 1 "" "")
9878 (match_operand 2 "" "")))
9879 (set (match_operand 3 "" "")
9880 (call (match_dup 1)
9881 (match_dup 2)))
9882 (clobber (match_operand:SI 4 "" ""))])]
9883 ""
9884 "")
9885
bd16a708
JW
9886;; ??? May eventually need all 6 versions of the call patterns with multiple
9887;; return values.
9888
8f7f2b3d
GRK
9889(define_insn "call_value_multiple_internal1"
9890 [(set (match_operand 0 "register_operand" "=df")
9891 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9892 (match_operand 2 "" "i")))
9893 (set (match_operand 3 "register_operand" "=df")
9894 (call (mem (match_dup 1))
9895 (match_dup 2)))
9896 (clobber (match_operand:SI 4 "register_operand" "=d"))]
9897 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9898 "*
9899{
9900 register rtx target = operands[1];
9901
9902 if (GET_CODE (target) == SYMBOL_REF)
9903 return \"%*jal\\t%1\";
9904 else if (GET_CODE (target) == CONST_INT)
9905 return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
9906 else
9907 return \"%*jal\\t%4,%1\";
9908}"
9909 [(set_attr "type" "call")
9910 (set_attr "mode" "none")])
9911
bd16a708
JW
9912(define_insn "call_value_multiple_internal2"
9913 [(set (match_operand 0 "register_operand" "=df")
aa4e54c4 9914 (call (mem (match_operand 1 "call_insn_operand" "ri"))
bd16a708
JW
9915 (match_operand 2 "" "i")))
9916 (set (match_operand 3 "register_operand" "=df")
aa4e54c4 9917 (call (mem (match_dup 1))
bd16a708
JW
9918 (match_dup 2)))
9919 (clobber (match_operand:SI 4 "register_operand" "=d"))]
9920 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9921 "*
9922{
aa4e54c4 9923 register rtx target = operands[1];
bd16a708
JW
9924
9925 if (GET_CODE (target) == SYMBOL_REF)
bd16a708 9926 {
5aae9091
JW
9927 if (GET_MODE (target) == SImode)
9928 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
bd16a708 9929 else
5aae9091 9930 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
bd16a708 9931 }
5aae9091
JW
9932 else if (GET_CODE (target) == CONST_INT)
9933 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
9934 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9935 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
9936 else
9937 return \"jal\\t%4,%1\";
bd16a708
JW
9938}"
9939 [(set_attr "type" "call")
9940 (set_attr "mode" "none")
0ff83799 9941 (set_attr "length" "8")])
bd16a708
JW
9942
9943
a93821e9
TW
9944;; Call subroutine returning any type.
9945
9946(define_expand "untyped_call"
9947 [(parallel [(call (match_operand 0 "" "")
9948 (const_int 0))
9949 (match_operand 1 "" "")
9950 (match_operand 2 "" "")])]
9951 ""
9952 "
9953{
740b4585 9954 if (operands[0]) /* silence statement not reached warnings */
a93821e9 9955 {
740b4585
MM
9956 int i;
9957
0499c2e4 9958 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
a93821e9 9959
740b4585
MM
9960 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9961 {
9962 rtx set = XVECEXP (operands[2], 0, i);
9963 emit_move_insn (SET_DEST (set), SET_SRC (set));
9964 }
a93821e9 9965
740b4585
MM
9966 emit_insn (gen_blockage ());
9967 DONE;
9968 }
a93821e9 9969}")
8ef30996
MM
9970\f
9971;;
9972;; ....................
9973;;
9974;; MISC.
9975;;
9976;; ....................
9977;;
9978
9979(define_insn "nop"
9980 [(const_int 0)]
9981 ""
9982 "%(nop%)"
9983 [(set_attr "type" "nop")
0ff83799 9984 (set_attr "mode" "none")])
8ef30996 9985
e454beb7
ILT
9986;; The MIPS chip does not seem to require stack probes.
9987;;
9988;; (define_expand "probe"
9989;; [(set (match_dup 0)
9990;; (match_dup 1))]
9991;; ""
9992;; "
9993;; {
9994;; operands[0] = gen_reg_rtx (SImode);
c5c76735 9995;; operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
e454beb7
ILT
9996;; MEM_VOLATILE_P (operands[1]) = TRUE;
9997;;
9998;; /* fall through and generate default code */
9999;; }")
10000;;
e19ff60f
JW
10001\f
10002;;
10003;; MIPS4 Conditional move instructions.
10004
10005(define_insn ""
10006 [(set (match_operand:SI 0 "register_operand" "=d,d")
10007 (if_then_else:SI
10008 (match_operator 4 "equality_op"
10009 [(match_operand:SI 1 "register_operand" "d,d")
10010 (const_int 0)])
10011 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10012 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
0025b7fa 10013 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
e19ff60f
JW
10014 "@
10015 mov%B4\\t%0,%z2,%1
10016 mov%b4\\t%0,%z3,%1"
10017 [(set_attr "type" "move")
10018 (set_attr "mode" "SI")])
10019
197b2bf3
JW
10020(define_insn ""
10021 [(set (match_operand:SI 0 "register_operand" "=d,d")
10022 (if_then_else:SI
10023 (match_operator 4 "equality_op"
1908a152 10024 [(match_operand:DI 1 "se_register_operand" "d,d")
197b2bf3
JW
10025 (const_int 0)])
10026 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
10027 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
0025b7fa 10028 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
197b2bf3
JW
10029 "@
10030 mov%B4\\t%0,%z2,%1
10031 mov%b4\\t%0,%z3,%1"
10032 [(set_attr "type" "move")
10033 (set_attr "mode" "SI")])
10034
e19ff60f
JW
10035(define_insn ""
10036 [(set (match_operand:SI 0 "register_operand" "=d,d")
10037 (if_then_else:SI
b8eb88d0
ILT
10038 (match_operator 3 "equality_op" [(match_operand:CC 4
10039 "register_operand"
10040 "z,z")
10041 (const_int 0)])
e19ff60f
JW
10042 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
10043 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
76ee8042 10044 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f 10045 "@
b8eb88d0
ILT
10046 mov%T3\\t%0,%z1,%4
10047 mov%t3\\t%0,%z2,%4"
e19ff60f
JW
10048 [(set_attr "type" "move")
10049 (set_attr "mode" "SI")])
10050
197b2bf3
JW
10051(define_insn ""
10052 [(set (match_operand:DI 0 "register_operand" "=d,d")
10053 (if_then_else:DI
10054 (match_operator 4 "equality_op"
10055 [(match_operand:SI 1 "register_operand" "d,d")
10056 (const_int 0)])
1908a152
ILT
10057 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10058 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
0025b7fa 10059 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
197b2bf3
JW
10060 "@
10061 mov%B4\\t%0,%z2,%1
10062 mov%b4\\t%0,%z3,%1"
10063 [(set_attr "type" "move")
10064 (set_attr "mode" "DI")])
10065
e19ff60f
JW
10066(define_insn ""
10067 [(set (match_operand:DI 0 "register_operand" "=d,d")
10068 (if_then_else:DI
10069 (match_operator 4 "equality_op"
1908a152 10070 [(match_operand:DI 1 "se_register_operand" "d,d")
e19ff60f 10071 (const_int 0)])
1908a152
ILT
10072 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10073 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
0025b7fa 10074 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
e19ff60f
JW
10075 "@
10076 mov%B4\\t%0,%z2,%1
10077 mov%b4\\t%0,%z3,%1"
10078 [(set_attr "type" "move")
10079 (set_attr "mode" "DI")])
10080
10081(define_insn ""
10082 [(set (match_operand:DI 0 "register_operand" "=d,d")
10083 (if_then_else:DI
b8eb88d0
ILT
10084 (match_operator 3 "equality_op" [(match_operand:CC 4
10085 "register_operand"
10086 "z,z")
10087 (const_int 0)])
1908a152
ILT
10088 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10089 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
76ee8042 10090 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f 10091 "@
b8eb88d0
ILT
10092 mov%T3\\t%0,%z1,%4
10093 mov%t3\\t%0,%z2,%4"
e19ff60f
JW
10094 [(set_attr "type" "move")
10095 (set_attr "mode" "DI")])
10096
10097(define_insn ""
10098 [(set (match_operand:SF 0 "register_operand" "=f,f")
10099 (if_then_else:SF
10100 (match_operator 4 "equality_op"
10101 [(match_operand:SI 1 "register_operand" "d,d")
10102 (const_int 0)])
10103 (match_operand:SF 2 "register_operand" "f,0")
10104 (match_operand:SF 3 "register_operand" "0,f")))]
76ee8042 10105 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f
JW
10106 "@
10107 mov%B4.s\\t%0,%2,%1
10108 mov%b4.s\\t%0,%3,%1"
10109 [(set_attr "type" "move")
10110 (set_attr "mode" "SF")])
10111
b3a79892
MM
10112(define_insn ""
10113 [(set (match_operand:SF 0 "register_operand" "=f,f")
10114 (if_then_else:SF
10115 (match_operator 4 "equality_op"
10116 [(match_operand:DI 1 "se_register_operand" "d,d")
10117 (const_int 0)])
10118 (match_operand:SF 2 "register_operand" "f,0")
10119 (match_operand:SF 3 "register_operand" "0,f")))]
76ee8042 10120 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
b3a79892
MM
10121 "@
10122 mov%B4.s\\t%0,%2,%1
10123 mov%b4.s\\t%0,%3,%1"
10124 [(set_attr "type" "move")
10125 (set_attr "mode" "SF")])
10126
e19ff60f
JW
10127(define_insn ""
10128 [(set (match_operand:SF 0 "register_operand" "=f,f")
10129 (if_then_else:SF
b8eb88d0
ILT
10130 (match_operator 3 "equality_op" [(match_operand:CC 4
10131 "register_operand"
10132 "z,z")
10133 (const_int 0)])
e19ff60f
JW
10134 (match_operand:SF 1 "register_operand" "f,0")
10135 (match_operand:SF 2 "register_operand" "0,f")))]
76ee8042 10136 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
e19ff60f 10137 "@
b8eb88d0
ILT
10138 mov%T3.s\\t%0,%1,%4
10139 mov%t3.s\\t%0,%2,%4"
e19ff60f
JW
10140 [(set_attr "type" "move")
10141 (set_attr "mode" "SF")])
10142
10143(define_insn ""
10144 [(set (match_operand:DF 0 "register_operand" "=f,f")
10145 (if_then_else:DF
10146 (match_operator 4 "equality_op"
10147 [(match_operand:SI 1 "register_operand" "d,d")
10148 (const_int 0)])
10149 (match_operand:DF 2 "register_operand" "f,0")
10150 (match_operand:DF 3 "register_operand" "0,f")))]
76ee8042 10151 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b3a79892
MM
10152 "@
10153 mov%B4.d\\t%0,%2,%1
10154 mov%b4.d\\t%0,%3,%1"
10155 [(set_attr "type" "move")
10156 (set_attr "mode" "DF")])
10157
10158(define_insn ""
10159 [(set (match_operand:DF 0 "register_operand" "=f,f")
10160 (if_then_else:DF
10161 (match_operator 4 "equality_op"
10162 [(match_operand:DI 1 "se_register_operand" "d,d")
10163 (const_int 0)])
10164 (match_operand:DF 2 "register_operand" "f,0")
10165 (match_operand:DF 3 "register_operand" "0,f")))]
76ee8042 10166 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f
JW
10167 "@
10168 mov%B4.d\\t%0,%2,%1
10169 mov%b4.d\\t%0,%3,%1"
10170 [(set_attr "type" "move")
10171 (set_attr "mode" "DF")])
10172
10173(define_insn ""
10174 [(set (match_operand:DF 0 "register_operand" "=f,f")
10175 (if_then_else:DF
b8eb88d0
ILT
10176 (match_operator 3 "equality_op" [(match_operand:CC 4
10177 "register_operand"
10178 "z,z")
10179 (const_int 0)])
e19ff60f
JW
10180 (match_operand:DF 1 "register_operand" "f,0")
10181 (match_operand:DF 2 "register_operand" "0,f")))]
76ee8042 10182 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
e19ff60f 10183 "@
b8eb88d0
ILT
10184 mov%T3.d\\t%0,%1,%4
10185 mov%t3.d\\t%0,%2,%4"
e19ff60f
JW
10186 [(set_attr "type" "move")
10187 (set_attr "mode" "DF")])
10188
10189;; These are the main define_expand's used to make conditional moves.
10190
10191(define_expand "movsicc"
10192 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10193 (set (match_operand:SI 0 "register_operand" "")
10194 (if_then_else:SI (match_dup 5)
10195 (match_operand:SI 2 "reg_or_0_operand" "")
10196 (match_operand:SI 3 "reg_or_0_operand" "")))]
0025b7fa 10197 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
e19ff60f
JW
10198 "
10199{
b8eb88d0
ILT
10200 gen_conditional_move (operands);
10201 DONE;
10202}")
e19ff60f 10203
b8eb88d0
ILT
10204(define_expand "movdicc"
10205 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10206 (set (match_operand:DI 0 "register_operand" "")
10207 (if_then_else:DI (match_dup 5)
1908a152
ILT
10208 (match_operand:DI 2 "se_reg_or_0_operand" "")
10209 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
0025b7fa 10210 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
b8eb88d0
ILT
10211 "
10212{
10213 gen_conditional_move (operands);
10214 DONE;
10215}")
e19ff60f 10216
b8eb88d0
ILT
10217(define_expand "movsfcc"
10218 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10219 (set (match_operand:SF 0 "register_operand" "")
10220 (if_then_else:SF (match_dup 5)
91760fce
ILT
10221 (match_operand:SF 2 "register_operand" "")
10222 (match_operand:SF 3 "register_operand" "")))]
76ee8042 10223 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
b8eb88d0
ILT
10224 "
10225{
10226 gen_conditional_move (operands);
10227 DONE;
e19ff60f
JW
10228}")
10229
b8eb88d0
ILT
10230(define_expand "movdfcc"
10231 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10232 (set (match_operand:DF 0 "register_operand" "")
10233 (if_then_else:DF (match_dup 5)
91760fce
ILT
10234 (match_operand:DF 2 "register_operand" "")
10235 (match_operand:DF 3 "register_operand" "")))]
76ee8042 10236 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
b8eb88d0
ILT
10237 "
10238{
10239 gen_conditional_move (operands);
10240 DONE;
10241}")
2bcb2ab3
GK
10242\f
10243;;
10244;; ....................
10245;;
10246;; mips16 inline constant tables
10247;;
10248;; ....................
10249;;
10250
10251(define_insn "consttable_qi"
10252 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
10253 "TARGET_MIPS16"
10254 "*
10255{
10256 assemble_integer (operands[0], 1, 1);
10257 return \"\";
10258}"
10259 [(set_attr "type" "unknown")
10260 (set_attr "mode" "QI")
0ff83799 10261 (set_attr "length" "8")])
2bcb2ab3
GK
10262
10263(define_insn "consttable_hi"
10264 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
10265 "TARGET_MIPS16"
10266 "*
10267{
10268 assemble_integer (operands[0], 2, 1);
10269 return \"\";
10270}"
10271 [(set_attr "type" "unknown")
10272 (set_attr "mode" "HI")
0ff83799 10273 (set_attr "length" "8")])
2bcb2ab3
GK
10274
10275(define_insn "consttable_si"
10276 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
10277 "TARGET_MIPS16"
10278 "*
10279{
10280 assemble_integer (operands[0], 4, 1);
10281 return \"\";
10282}"
10283 [(set_attr "type" "unknown")
10284 (set_attr "mode" "SI")
0ff83799 10285 (set_attr "length" "8")])
2bcb2ab3
GK
10286
10287(define_insn "consttable_di"
10288 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
10289 "TARGET_MIPS16"
10290 "*
10291{
10292 assemble_integer (operands[0], 8, 1);
10293 return \"\";
10294}"
10295 [(set_attr "type" "unknown")
10296 (set_attr "mode" "DI")
0ff83799 10297 (set_attr "length" "16")])
2bcb2ab3
GK
10298
10299(define_insn "consttable_sf"
10300 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
10301 "TARGET_MIPS16"
10302 "*
10303{
10304 union real_extract u;
10305
10306 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10307 abort ();
4e135bdd 10308 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
2bcb2ab3
GK
10309 assemble_real (u.d, SFmode);
10310 return \"\";
10311}"
10312 [(set_attr "type" "unknown")
10313 (set_attr "mode" "SF")
0ff83799 10314 (set_attr "length" "8")])
2bcb2ab3
GK
10315
10316(define_insn "consttable_df"
10317 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
10318 "TARGET_MIPS16"
10319 "*
10320{
10321 union real_extract u;
10322
10323 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10324 abort ();
4e135bdd 10325 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
2bcb2ab3
GK
10326 assemble_real (u.d, DFmode);
10327 return \"\";
10328}"
10329 [(set_attr "type" "unknown")
10330 (set_attr "mode" "DF")
0ff83799 10331 (set_attr "length" "16")])
2bcb2ab3
GK
10332
10333(define_insn "align_2"
10334 [(unspec_volatile [(const_int 0)] 16)]
10335 "TARGET_MIPS16"
10336 ".align 1"
10337 [(set_attr "type" "unknown")
10338 (set_attr "mode" "HI")
0ff83799 10339 (set_attr "length" "8")])
2bcb2ab3
GK
10340
10341(define_insn "align_4"
10342 [(unspec_volatile [(const_int 0)] 17)]
10343 "TARGET_MIPS16"
10344 ".align 2"
10345 [(set_attr "type" "unknown")
10346 (set_attr "mode" "SI")
0ff83799 10347 (set_attr "length" "8")])
2bcb2ab3
GK
10348
10349(define_insn "align_8"
10350 [(unspec_volatile [(const_int 0)] 18)]
10351 "TARGET_MIPS16"
10352 ".align 3"
10353 [(set_attr "type" "unknown")
10354 (set_attr "mode" "DI")
0ff83799 10355 (set_attr "length" "12")])
2bcb2ab3
GK
10356\f
10357;;
10358;; ....................
10359;;
10360;; mips16 peepholes
10361;;
10362;; ....................
10363;;
10364
10365;; On the mips16, reload will sometimes decide that a pseudo register
10366;; should go into $24, and then later on have to reload that register.
10367;; When that happens, we get a load of a general register followed by
10368;; a move from the general register to $24 followed by a branch.
10369;; These peepholes catch the common case, and fix it to just use the
10370;; general register for the branch.
10371
10372(define_peephole
10373 [(set (match_operand:SI 0 "register_operand" "=t")
10374 (match_operand:SI 1 "register_operand" "d"))
10375 (set (pc)
10376 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10377 (const_int 0)])
10378 (match_operand 3 "pc_or_label_operand" "")
10379 (match_operand 4 "pc_or_label_operand" "")))]
10380 "TARGET_MIPS16
10381 && GET_CODE (operands[0]) == REG
10382 && REGNO (operands[0]) == 24
10383 && dead_or_set_p (insn, operands[0])
10384 && GET_CODE (operands[1]) == REG
10385 && M16_REG_P (REGNO (operands[1]))"
10386 "*
10387{
10388 if (operands[3] != pc_rtx)
10389 return \"%*b%C2z\\t%1,%3\";
10390 else
10391 return \"%*b%N2z\\t%1,%4\";
10392}"
10393 [(set_attr "type" "branch")
10394 (set_attr "mode" "none")
0ff83799 10395 (set_attr "length" "8")])
2bcb2ab3
GK
10396
10397(define_peephole
10398 [(set (match_operand:DI 0 "register_operand" "=t")
10399 (match_operand:DI 1 "register_operand" "d"))
10400 (set (pc)
10401 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10402 (const_int 0)])
10403 (match_operand 3 "pc_or_label_operand" "")
10404 (match_operand 4 "pc_or_label_operand" "")))]
10405 "TARGET_MIPS16 && TARGET_64BIT
10406 && GET_CODE (operands[0]) == REG
10407 && REGNO (operands[0]) == 24
10408 && dead_or_set_p (insn, operands[0])
10409 && GET_CODE (operands[1]) == REG
10410 && M16_REG_P (REGNO (operands[1]))"
10411 "*
10412{
10413 if (operands[3] != pc_rtx)
10414 return \"%*b%C2z\\t%1,%3\";
10415 else
10416 return \"%*b%N2z\\t%1,%4\";
10417}"
10418 [(set_attr "type" "branch")
10419 (set_attr "mode" "none")
0ff83799 10420 (set_attr "length" "8")])
2bcb2ab3
GK
10421
10422;; We can also have the reverse reload: reload will spill $24 into
10423;; another register, and then do a branch on that register when it
10424;; could have just stuck with $24.
10425
10426(define_peephole
10427 [(set (match_operand:SI 0 "register_operand" "=d")
10428 (match_operand:SI 1 "register_operand" "t"))
10429 (set (pc)
10430 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10431 (const_int 0)])
10432 (match_operand 3 "pc_or_label_operand" "")
10433 (match_operand 4 "pc_or_label_operand" "")))]
10434 "TARGET_MIPS16
10435 && GET_CODE (operands[1]) == REG
10436 && REGNO (operands[1]) == 24
10437 && GET_CODE (operands[0]) == REG
10438 && M16_REG_P (REGNO (operands[0]))
10439 && dead_or_set_p (insn, operands[0])"
10440 "*
10441{
10442 if (operands[3] != pc_rtx)
10443 return \"%*bt%C2z\\t%3\";
10444 else
10445 return \"%*bt%N2z\\t%4\";
10446}"
10447 [(set_attr "type" "branch")
10448 (set_attr "mode" "none")
0ff83799 10449 (set_attr "length" "8")])
2bcb2ab3
GK
10450
10451(define_peephole
10452 [(set (match_operand:DI 0 "register_operand" "=d")
10453 (match_operand:DI 1 "register_operand" "t"))
10454 (set (pc)
10455 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10456 (const_int 0)])
10457 (match_operand 3 "pc_or_label_operand" "")
10458 (match_operand 4 "pc_or_label_operand" "")))]
10459 "TARGET_MIPS16 && TARGET_64BIT
10460 && GET_CODE (operands[1]) == REG
10461 && REGNO (operands[1]) == 24
10462 && GET_CODE (operands[0]) == REG
10463 && M16_REG_P (REGNO (operands[0]))
10464 && dead_or_set_p (insn, operands[0])"
10465 "*
10466{
10467 if (operands[3] != pc_rtx)
10468 return \"%*bt%C2z\\t%3\";
10469 else
10470 return \"%*bt%N2z\\t%4\";
10471}"
10472 [(set_attr "type" "branch")
10473 (set_attr "mode" "none")
0ff83799 10474 (set_attr "length" "8")])
be8b493b
JL
10475
10476;; For the rare case where we need to load an address into a register
10477;; that can not be recognized by the normal movsi/addsi instructions.
10478;; I have no idea how many insns this can actually generate. It should
10479;; be rare, so over-estimating as 10 instructions should not have any
10480;; real performance impact.
10481(define_insn "leasi"
10482 [(set (match_operand:SI 0 "register_operand" "=d")
10483 (match_operand:SI 1 "address_operand" "p"))]
10484 "Pmode == SImode"
10485 "la %0,%a1"
10486 [(set_attr "type" "arith")
10487 (set_attr "mode" "SI")
10488 (set_attr "length" "40")])
10489
10490;; Similarly for targets where we have 64bit pointers.
10491(define_insn "leadi"
10492 [(set (match_operand:DI 0 "register_operand" "=d")
10493 (match_operand:DI 1 "address_operand" "p"))]
10494 "Pmode == DImode"
10495 "la %0,%a1"
10496 [(set_attr "type" "arith")
10497 (set_attr "mode" "DI")
10498 (set_attr "length" "40")])
This page took 2.339972 seconds and 5 git commands to generate.