]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mips/mips.md
7b860edc652671b7c158f6e1793012840916eea7
[thirdparty/gcc.git] / gcc / config / mips / mips.md
1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
3 ;; Changes by Michael Meissner, meissner@osf.org
4 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
5 ;; Brendan Eich, brendan@microunity.com.
6 ;; Copyright (C) 1989, 90-98, 1999 Free Software Foundation, Inc.
7
8 ;; This file is part of GNU CC.
9
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;; ??? Currently does not have define_function_unit support for the R8000.
26 ;; Must include new entries for fmadd in addition to existing entries.
27
28 \f
29
30 ;; ....................
31 ;;
32 ;; Attributes
33 ;;
34 ;; ....................
35
36 ;; Classification of each insn.
37 ;; branch conditional branch
38 ;; jump unconditional jump
39 ;; call unconditional call
40 ;; load load instruction(s)
41 ;; store store instruction(s)
42 ;; move data movement within same register set
43 ;; xfer transfer to/from coprocessor
44 ;; hilo transfer of hi/lo registers
45 ;; arith integer arithmetic instruction
46 ;; darith double precision integer arithmetic instructions
47 ;; imul integer multiply
48 ;; idiv integer divide
49 ;; icmp integer compare
50 ;; fadd floating point add/subtract
51 ;; fmul floating point multiply
52 ;; fmadd floating point multiply-add
53 ;; fdiv floating point divide
54 ;; fabs floating point absolute value
55 ;; fneg floating point negation
56 ;; fcmp floating point compare
57 ;; fcvt floating point convert
58 ;; fsqrt floating point square root
59 ;; multi multiword sequence (or user asm statements)
60 ;; nop no operation
61
62 (define_attr "type"
63 "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"
64 (const_string "unknown"))
65
66 ;; Main data type used by the insn
67 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
68
69 ;; Length (in # of bytes). A conditional branch is allowed only to a
70 ;; location within a signed 18-bit offset of the delay slot. If that
71 ;; provides too smal a range, we use the `j' instruction. This
72 ;; instruction takes a 28-bit value, but that value is not an offset.
73 ;; Instead, it's bitwise-ored with the high-order four bits of the
74 ;; instruction in the delay slot, which means it cannot be used to
75 ;; cross a 256MB boundary. We could fall back back on the jr,
76 ;; instruction which allows full access to the entire address space,
77 ;; but we do not do so at present.
78
79 (define_attr "length" ""
80 (cond [(eq_attr "type" "branch")
81 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
82 (const_int 131072))
83 (const_int 4)]
84 (const_int 12))]
85 (const_int 4)))
86
87 ;; Attribute describing the processor. This attribute must match exactly
88 ;; with the processor_type enumeration in mips.h.
89
90 ;; Attribute describing the processor
91 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
92 ;; (const
93 ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
94 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
95 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
96 ;; (const_string "default"))))
97
98 ;; ??? Fix everything that tests this attribute.
99 (define_attr "cpu"
100 "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
101 (const (symbol_ref "mips_cpu_attr")))
102
103 ;; Does the instruction have a mandatory delay slot?
104 ;; The 3900, is (mostly) mips1, but does not have a mandatory load delay
105 ;; slot.
106 (define_attr "dslot" "no,yes"
107 (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
108 (and (eq_attr "type" "load")
109 (and (eq (symbol_ref "mips_isa") (const_int 1))
110 (and (eq (symbol_ref "mips16") (const_int 0))
111 (eq_attr "cpu" "!r3900")))))
112 (const_string "yes")
113 (const_string "no")))
114
115 ;; Attribute defining whether or not we can use the branch-likely instructions
116
117 (define_attr "branch_likely" "no,yes"
118 (const
119 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
120 (const_string "yes")
121 (const_string "no"))))
122
123
124 ;; Describe a user's asm statement.
125 (define_asm_attributes
126 [(set_attr "type" "multi")])
127
128 ;; whether or not generating calls to position independent functions
129 (define_attr "abicalls" "no,yes"
130 (const (symbol_ref "mips_abicalls_attr")))
131
132 \f
133
134 ;; .........................
135 ;;
136 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
137 ;;
138 ;; .........................
139
140 (define_delay (and (eq_attr "type" "branch")
141 (eq (symbol_ref "mips16") (const_int 0)))
142 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
143 (nil)
144 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])
145
146 (define_delay (eq_attr "type" "jump")
147 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
148 (nil)
149 (nil)])
150
151 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
152 [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
153 (nil)
154 (nil)])
155
156 \f
157
158 ;; .........................
159 ;;
160 ;; Functional units
161 ;;
162 ;; .........................
163
164 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
165 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
166
167 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
168
169 (define_function_unit "memory" 1 0
170 (and (eq_attr "type" "load")
171 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
172 3 0)
173
174 (define_function_unit "memory" 1 0
175 (and (eq_attr "type" "load")
176 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
177 2 0)
178
179 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
180
181 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
182
183 (define_function_unit "imuldiv" 1 0
184 (eq_attr "type" "hilo")
185 1 3)
186
187 (define_function_unit "imuldiv" 1 0
188 (and (eq_attr "type" "imul")
189 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
190 17 17)
191
192 ;; On them mips16, we want to stronly discourage a mult from appearing
193 ;; after an mflo, since that requires explicit nop instructions. We
194 ;; do this by pretending that mflo ties up the function unit for long
195 ;; enough that the scheduler will ignore load stalls and the like when
196 ;; selecting instructions to between the two instructions.
197
198 (define_function_unit "imuldiv" 1 0
199 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
200 1 5)
201
202 (define_function_unit "imuldiv" 1 0
203 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
204 12 12)
205
206 (define_function_unit "imuldiv" 1 0
207 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
208 10 10)
209
210 (define_function_unit "imuldiv" 1 0
211 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
212 4 4)
213
214 (define_function_unit "imuldiv" 1 0
215 (and (eq_attr "type" "imul")
216 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
217 1 1)
218
219 (define_function_unit "imuldiv" 1 0
220 (and (eq_attr "type" "imul")
221 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
222 4 4)
223
224 (define_function_unit "imuldiv" 1 0
225 (and (eq_attr "type" "imul")
226 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
227 5 5)
228
229 (define_function_unit "imuldiv" 1 0
230 (and (eq_attr "type" "imul")
231 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
232 8 8)
233
234 (define_function_unit "imuldiv" 1 0
235 (and (eq_attr "type" "imul")
236 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
237 9 9)
238
239 (define_function_unit "imuldiv" 1 0
240 (and (eq_attr "type" "idiv")
241 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
242 38 38)
243
244 (define_function_unit "imuldiv" 1 0
245 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
246 35 35)
247
248 (define_function_unit "imuldiv" 1 0
249 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
250 42 42)
251
252 (define_function_unit "imuldiv" 1 0
253 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
254 36 36)
255
256 (define_function_unit "imuldiv" 1 0
257 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
258 69 69)
259
260 (define_function_unit "imuldiv" 1 0
261 (and (eq_attr "type" "idiv")
262 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
263 35 35)
264
265 (define_function_unit "imuldiv" 1 0
266 (and (eq_attr "type" "idiv")
267 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
268 67 67)
269
270 (define_function_unit "imuldiv" 1 0
271 (and (eq_attr "type" "idiv")
272 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
273 37 37)
274
275 (define_function_unit "imuldiv" 1 0
276 (and (eq_attr "type" "idiv")
277 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
278 69 69)
279
280 (define_function_unit "imuldiv" 1 0
281 (and (eq_attr "type" "idiv")
282 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
283 36 36)
284
285 (define_function_unit "imuldiv" 1 0
286 (and (eq_attr "type" "idiv")
287 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
288 68 68)
289
290 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
291 ;; the FP hardware is part of the normal ALU circuitry. This means FP
292 ;; instructions affect the pipe-line, and no functional unit
293 ;; parallelism can occur on R4300 processors. To force GCC into coding
294 ;; for only a single functional unit, we force the R4300 FP
295 ;; instructions to be processed in the "imuldiv" unit.
296
297 (define_function_unit "adder" 1 1
298 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
299 3 0)
300
301 (define_function_unit "adder" 1 1
302 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
303 2 0)
304
305 (define_function_unit "adder" 1 1
306 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
307 1 0)
308
309 (define_function_unit "adder" 1 1
310 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
311 4 0)
312
313 (define_function_unit "adder" 1 1
314 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
315 2 0)
316
317 (define_function_unit "adder" 1 1
318 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
319 3 0)
320
321 (define_function_unit "adder" 1 1
322 (and (eq_attr "type" "fabs,fneg")
323 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
324 2 0)
325
326 (define_function_unit "adder" 1 1
327 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
328 1 0)
329
330 (define_function_unit "mult" 1 1
331 (and (eq_attr "type" "fmul")
332 (and (eq_attr "mode" "SF")
333 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
334 7 0)
335
336 (define_function_unit "mult" 1 1
337 (and (eq_attr "type" "fmul")
338 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
339 4 0)
340
341 (define_function_unit "mult" 1 1
342 (and (eq_attr "type" "fmul")
343 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
344 5 0)
345
346 (define_function_unit "mult" 1 1
347 (and (eq_attr "type" "fmul")
348 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
349 8 0)
350
351 (define_function_unit "mult" 1 1
352 (and (eq_attr "type" "fmul")
353 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
354 8 0)
355
356 (define_function_unit "mult" 1 1
357 (and (eq_attr "type" "fmul")
358 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
359 5 0)
360
361 (define_function_unit "mult" 1 1
362 (and (eq_attr "type" "fmul")
363 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
364 6 0)
365
366 (define_function_unit "divide" 1 1
367 (and (eq_attr "type" "fdiv")
368 (and (eq_attr "mode" "SF")
369 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
370 23 0)
371
372 (define_function_unit "divide" 1 1
373 (and (eq_attr "type" "fdiv")
374 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
375 12 0)
376
377 (define_function_unit "divide" 1 1
378 (and (eq_attr "type" "fdiv")
379 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
380 15 0)
381
382 (define_function_unit "divide" 1 1
383 (and (eq_attr "type" "fdiv")
384 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
385 32 0)
386
387 (define_function_unit "divide" 1 1
388 (and (eq_attr "type" "fdiv")
389 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
390 21 0)
391
392 (define_function_unit "divide" 1 1
393 (and (eq_attr "type" "fdiv")
394 (and (eq_attr "mode" "DF")
395 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
396 36 0)
397
398 (define_function_unit "divide" 1 1
399 (and (eq_attr "type" "fdiv")
400 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
401 19 0)
402
403 (define_function_unit "divide" 1 1
404 (and (eq_attr "type" "fdiv")
405 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
406 16 0)
407
408 (define_function_unit "divide" 1 1
409 (and (eq_attr "type" "fdiv")
410 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
411 61 0)
412
413 ;;; ??? Is this number right?
414 (define_function_unit "divide" 1 1
415 (and (eq_attr "type" "fsqrt")
416 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
417 54 0)
418
419 (define_function_unit "divide" 1 1
420 (and (eq_attr "type" "fsqrt")
421 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
422 31 0)
423
424 (define_function_unit "divide" 1 1
425 (and (eq_attr "type" "fsqrt")
426 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
427 21 0)
428
429 ;;; ??? Is this number right?
430 (define_function_unit "divide" 1 1
431 (and (eq_attr "type" "fsqrt")
432 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
433 112 0)
434
435 (define_function_unit "divide" 1 1
436 (and (eq_attr "type" "fsqrt")
437 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
438 60 0)
439
440 (define_function_unit "divide" 1 1
441 (and (eq_attr "type" "fsqrt")
442 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
443 36 0)
444
445 ;; R4300 FP instruction classes treated as part of the "imuldiv"
446 ;; functional unit:
447
448 (define_function_unit "imuldiv" 1 0
449 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
450 3 3)
451
452 (define_function_unit "imuldiv" 1 0
453 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
454 1 1)
455
456 (define_function_unit "imuldiv" 1 0
457 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
458 5 5)
459 (define_function_unit "imuldiv" 1 0
460 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
461 8 8)
462
463 (define_function_unit "imuldiv" 1 0
464 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
465 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
466 29 29)
467 (define_function_unit "imuldiv" 1 0
468 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
469 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
470 58 58)
471 \f
472 ;; The following functional units do not use the cpu type, and use
473 ;; much less memory in genattrtab.c.
474
475 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
476 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
477 ;;
478 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
479 ;;
480 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
481 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
482 ;;
483 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
484 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
485 ;;
486 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
487 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
488 ;;
489 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
490 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
491 ;;
492 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
493 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
494 ;;
495 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
496 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
497
498 \f
499 ;;
500 ;; ....................
501 ;;
502 ;; ADDITION
503 ;;
504 ;; ....................
505 ;;
506
507 (define_insn "adddf3"
508 [(set (match_operand:DF 0 "register_operand" "=f")
509 (plus:DF (match_operand:DF 1 "register_operand" "f")
510 (match_operand:DF 2 "register_operand" "f")))]
511 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
512 "add.d\\t%0,%1,%2"
513 [(set_attr "type" "fadd")
514 (set_attr "mode" "DF")])
515
516 (define_insn "addsf3"
517 [(set (match_operand:SF 0 "register_operand" "=f")
518 (plus:SF (match_operand:SF 1 "register_operand" "f")
519 (match_operand:SF 2 "register_operand" "f")))]
520 "TARGET_HARD_FLOAT"
521 "add.s\\t%0,%1,%2"
522 [(set_attr "type" "fadd")
523 (set_attr "mode" "SF")])
524
525 (define_expand "addsi3"
526 [(set (match_operand:SI 0 "register_operand" "=d")
527 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
528 (match_operand:SI 2 "arith_operand" "dI")))]
529 ""
530 "
531 {
532 /* The mips16 assembler handles -32768 correctly, and so does gas,
533 but some other MIPS assemblers think that -32768 needs to be
534 loaded into a register before it can be added in. */
535 if (! TARGET_MIPS16
536 && ! TARGET_GAS
537 && GET_CODE (operands[2]) == CONST_INT
538 && INTVAL (operands[2]) == -32768)
539 operands[2] = force_reg (SImode, operands[2]);
540 }")
541
542 (define_insn "addsi3_internal"
543 [(set (match_operand:SI 0 "register_operand" "=d")
544 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
545 (match_operand:SI 2 "arith_operand" "dI")))]
546 "! TARGET_MIPS16
547 && (TARGET_GAS
548 || GET_CODE (operands[2]) != CONST_INT
549 || INTVAL (operands[2]) != -32768)"
550 "addu\\t%0,%z1,%2"
551 [(set_attr "type" "arith")
552 (set_attr "mode" "SI")])
553
554 ;; For the mips16, we need to recognize stack pointer additions
555 ;; explicitly, since we don't have a constraint for $sp. These insns
556 ;; will be generated by the save_restore_insns functions.
557
558 (define_insn ""
559 [(set (reg:SI 29)
560 (plus:SI (reg:SI 29)
561 (match_operand:SI 0 "small_int" "I")))]
562 "TARGET_MIPS16"
563 "addu\\t%$,%$,%0"
564 [(set_attr "type" "arith")
565 (set_attr "mode" "SI")
566 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
567 (const_int 4)
568 (const_int 8)))])
569
570 (define_insn ""
571 [(set (match_operand:SI 0 "register_operand" "=d")
572 (plus:SI (reg:SI 29)
573 (match_operand:SI 1 "small_int" "I")))]
574 "TARGET_MIPS16"
575 "addu\\t%0,%$,%1"
576 [(set_attr "type" "arith")
577 (set_attr "mode" "SI")
578 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
579 (const_int 4)
580 (const_int 8)))])
581
582 (define_insn ""
583 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
584 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
585 (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
586 "TARGET_MIPS16
587 && (GET_CODE (operands[1]) != REG
588 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
589 || M16_REG_P (REGNO (operands[1]))
590 || REGNO (operands[1]) == ARG_POINTER_REGNUM
591 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
592 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
593 && (GET_CODE (operands[2]) != REG
594 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
595 || M16_REG_P (REGNO (operands[2]))
596 || REGNO (operands[2]) == ARG_POINTER_REGNUM
597 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
598 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
599 "*
600 {
601 if (REGNO (operands[0]) == REGNO (operands[1]))
602 return \"addu\\t%0,%2\";
603 return \"addu\\t%0,%1,%2\";
604 }"
605 [(set_attr "type" "arith")
606 (set_attr "mode" "SI")
607 (set_attr_alternative "length"
608 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
609 (const_int 4)
610 (const_int 8))
611 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
612 (const_int 4)
613 (const_int 8))
614 (const_int 4)])])
615
616
617 ;; On the mips16, we can sometimes split an add of a constant which is
618 ;; a 4 byte instruction into two adds which are both 2 byte
619 ;; instructions. There are two cases: one where we are adding a
620 ;; constant plus a register to another register, and one where we are
621 ;; simply adding a constant to a register.
622
623 (define_split
624 [(set (match_operand:SI 0 "register_operand" "")
625 (plus:SI (match_dup 0)
626 (match_operand:SI 1 "const_int_operand" "")))]
627 "TARGET_MIPS16 && reload_completed
628 && GET_CODE (operands[0]) == REG
629 && M16_REG_P (REGNO (operands[0]))
630 && GET_CODE (operands[1]) == CONST_INT
631 && ((INTVAL (operands[1]) > 0x7f
632 && INTVAL (operands[1]) <= 0x7f + 0x7f)
633 || (INTVAL (operands[1]) < - 0x80
634 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
635 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
636 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
637 "
638 {
639 HOST_WIDE_INT val = INTVAL (operands[1]);
640
641 if (val >= 0)
642 {
643 operands[1] = GEN_INT (0x7f);
644 operands[2] = GEN_INT (val - 0x7f);
645 }
646 else
647 {
648 operands[1] = GEN_INT (- 0x80);
649 operands[2] = GEN_INT (val + 0x80);
650 }
651 }")
652
653 (define_split
654 [(set (match_operand:SI 0 "register_operand" "")
655 (plus:SI (match_operand:SI 1 "register_operand" "")
656 (match_operand:SI 2 "const_int_operand" "")))]
657 "TARGET_MIPS16 && reload_completed
658 && GET_CODE (operands[0]) == REG
659 && M16_REG_P (REGNO (operands[0]))
660 && GET_CODE (operands[1]) == REG
661 && M16_REG_P (REGNO (operands[1]))
662 && REGNO (operands[0]) != REGNO (operands[1])
663 && GET_CODE (operands[2]) == CONST_INT
664 && ((INTVAL (operands[2]) > 0x7
665 && INTVAL (operands[2]) <= 0x7 + 0x7f)
666 || (INTVAL (operands[2]) < - 0x8
667 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
668 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
669 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
670 "
671 {
672 HOST_WIDE_INT val = INTVAL (operands[2]);
673
674 if (val >= 0)
675 {
676 operands[2] = GEN_INT (0x7);
677 operands[3] = GEN_INT (val - 0x7);
678 }
679 else
680 {
681 operands[2] = GEN_INT (- 0x8);
682 operands[3] = GEN_INT (val + 0x8);
683 }
684 }")
685
686 (define_expand "adddi3"
687 [(parallel [(set (match_operand:DI 0 "register_operand" "")
688 (plus:DI (match_operand:DI 1 "se_register_operand" "")
689 (match_operand:DI 2 "se_arith_operand" "")))
690 (clobber (match_dup 3))])]
691 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
692 "
693 {
694 /* The mips16 assembler handles -32768 correctly, and so does gas,
695 but some other MIPS assemblers think that -32768 needs to be
696 loaded into a register before it can be added in. */
697 if (! TARGET_MIPS16
698 && ! TARGET_GAS
699 && GET_CODE (operands[2]) == CONST_INT
700 && INTVAL (operands[2]) == -32768)
701 operands[2] = force_reg (DImode, operands[2]);
702
703 if (TARGET_64BIT)
704 {
705 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
706 operands[2]));
707 DONE;
708 }
709
710 operands[3] = gen_reg_rtx (SImode);
711 }")
712
713 (define_insn "adddi3_internal_1"
714 [(set (match_operand:DI 0 "register_operand" "=d,&d")
715 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
716 (match_operand:DI 2 "register_operand" "d,d")))
717 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
718 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
719 "*
720 {
721 return (REGNO (operands[0]) == REGNO (operands[1])
722 && REGNO (operands[0]) == REGNO (operands[2]))
723 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
724 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
725 }"
726 [(set_attr "type" "darith")
727 (set_attr "mode" "DI")
728 (set_attr "length" "16")])
729
730 (define_split
731 [(set (match_operand:DI 0 "register_operand" "")
732 (plus:DI (match_operand:DI 1 "register_operand" "")
733 (match_operand:DI 2 "register_operand" "")))
734 (clobber (match_operand:SI 3 "register_operand" ""))]
735 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
736 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
737 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
738 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
739 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
740 && (REGNO (operands[0]) != REGNO (operands[1])
741 || REGNO (operands[0]) != REGNO (operands[2]))"
742
743 [(set (subreg:SI (match_dup 0) 0)
744 (plus:SI (subreg:SI (match_dup 1) 0)
745 (subreg:SI (match_dup 2) 0)))
746
747 (set (match_dup 3)
748 (ltu:SI (subreg:SI (match_dup 0) 0)
749 (subreg:SI (match_dup 2) 0)))
750
751 (set (subreg:SI (match_dup 0) 1)
752 (plus:SI (subreg:SI (match_dup 1) 1)
753 (subreg:SI (match_dup 2) 1)))
754
755 (set (subreg:SI (match_dup 0) 1)
756 (plus:SI (subreg:SI (match_dup 0) 1)
757 (match_dup 3)))]
758 "")
759
760 (define_split
761 [(set (match_operand:DI 0 "register_operand" "")
762 (plus:DI (match_operand:DI 1 "register_operand" "")
763 (match_operand:DI 2 "register_operand" "")))
764 (clobber (match_operand:SI 3 "register_operand" ""))]
765 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
766 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
767 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
768 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
769 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
770 && (REGNO (operands[0]) != REGNO (operands[1])
771 || REGNO (operands[0]) != REGNO (operands[2]))"
772
773 [(set (subreg:SI (match_dup 0) 1)
774 (plus:SI (subreg:SI (match_dup 1) 1)
775 (subreg:SI (match_dup 2) 1)))
776
777 (set (match_dup 3)
778 (ltu:SI (subreg:SI (match_dup 0) 1)
779 (subreg:SI (match_dup 2) 1)))
780
781 (set (subreg:SI (match_dup 0) 0)
782 (plus:SI (subreg:SI (match_dup 1) 0)
783 (subreg:SI (match_dup 2) 0)))
784
785 (set (subreg:SI (match_dup 0) 0)
786 (plus:SI (subreg:SI (match_dup 0) 0)
787 (match_dup 3)))]
788 "")
789
790 (define_insn "adddi3_internal_2"
791 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
792 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
793 (match_operand:DI 2 "small_int" "P,J,N")))
794 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
795 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
796 && (TARGET_GAS
797 || GET_CODE (operands[2]) != CONST_INT
798 || INTVAL (operands[2]) != -32768)"
799 "@
800 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
801 move\\t%L0,%L1\;move\\t%M0,%M1
802 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
803 [(set_attr "type" "darith")
804 (set_attr "mode" "DI")
805 (set_attr "length" "12,8,16")])
806
807 (define_split
808 [(set (match_operand:DI 0 "register_operand" "")
809 (plus:DI (match_operand:DI 1 "register_operand" "")
810 (match_operand:DI 2 "small_int" "")))
811 (clobber (match_operand:SI 3 "register_operand" "=d"))]
812 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
813 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
814 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
815 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
816 && INTVAL (operands[2]) > 0"
817
818 [(set (subreg:SI (match_dup 0) 0)
819 (plus:SI (subreg:SI (match_dup 1) 0)
820 (match_dup 2)))
821
822 (set (match_dup 3)
823 (ltu:SI (subreg:SI (match_dup 0) 0)
824 (match_dup 2)))
825
826 (set (subreg:SI (match_dup 0) 1)
827 (plus:SI (subreg:SI (match_dup 1) 1)
828 (match_dup 3)))]
829 "")
830
831 (define_split
832 [(set (match_operand:DI 0 "register_operand" "")
833 (plus:DI (match_operand:DI 1 "register_operand" "")
834 (match_operand:DI 2 "small_int" "")))
835 (clobber (match_operand:SI 3 "register_operand" "=d"))]
836 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
837 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
838 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
839 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
840 && INTVAL (operands[2]) > 0"
841
842 [(set (subreg:SI (match_dup 0) 1)
843 (plus:SI (subreg:SI (match_dup 1) 1)
844 (match_dup 2)))
845
846 (set (match_dup 3)
847 (ltu:SI (subreg:SI (match_dup 0) 1)
848 (match_dup 2)))
849
850 (set (subreg:SI (match_dup 0) 0)
851 (plus:SI (subreg:SI (match_dup 1) 0)
852 (match_dup 3)))]
853 "")
854
855 (define_insn "adddi3_internal_3"
856 [(set (match_operand:DI 0 "register_operand" "=d")
857 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
858 (match_operand:DI 2 "se_arith_operand" "dI")))]
859 "TARGET_64BIT
860 && !TARGET_MIPS16
861 && (TARGET_GAS
862 || GET_CODE (operands[2]) != CONST_INT
863 || INTVAL (operands[2]) != -32768)"
864 "*
865 {
866 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
867 ? \"dsubu\\t%0,%z1,%n2\"
868 : \"daddu\\t%0,%z1,%2\";
869 }"
870 [(set_attr "type" "darith")
871 (set_attr "mode" "DI")])
872
873 ;; For the mips16, we need to recognize stack pointer additions
874 ;; explicitly, since we don't have a constraint for $sp. These insns
875 ;; will be generated by the save_restore_insns functions.
876
877 (define_insn ""
878 [(set (reg:DI 29)
879 (plus:DI (reg:DI 29)
880 (match_operand:DI 0 "small_int" "I")))]
881 "TARGET_MIPS16 && TARGET_64BIT"
882 "daddu\\t%$,%$,%0"
883 [(set_attr "type" "arith")
884 (set_attr "mode" "DI")
885 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
886 (const_int 4)
887 (const_int 8)))])
888
889 (define_insn ""
890 [(set (match_operand:DI 0 "register_operand" "=d")
891 (plus:DI (reg:DI 29)
892 (match_operand:DI 1 "small_int" "I")))]
893 "TARGET_MIPS16 && TARGET_64BIT"
894 "daddu\\t%0,%$,%1"
895 [(set_attr "type" "arith")
896 (set_attr "mode" "DI")
897 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
898 (const_int 4)
899 (const_int 8)))])
900
901 (define_insn ""
902 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
903 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
904 (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
905 "TARGET_MIPS16 && TARGET_64BIT
906 && (GET_CODE (operands[1]) != REG
907 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
908 || M16_REG_P (REGNO (operands[1]))
909 || REGNO (operands[1]) == ARG_POINTER_REGNUM
910 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
911 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
912 && (GET_CODE (operands[2]) != REG
913 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
914 || M16_REG_P (REGNO (operands[2]))
915 || REGNO (operands[2]) == ARG_POINTER_REGNUM
916 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
917 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
918 "*
919 {
920 if (REGNO (operands[0]) == REGNO (operands[1]))
921 return \"daddu\\t%0,%2\";
922 return \"daddu\\t%0,%1,%2\";
923 }"
924 [(set_attr "type" "arith")
925 (set_attr "mode" "DI")
926 (set_attr_alternative "length"
927 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
928 (const_int 4)
929 (const_int 8))
930 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
931 (const_int 4)
932 (const_int 8))
933 (const_int 4)])])
934
935
936 ;; On the mips16, we can sometimes split an add of a constant which is
937 ;; a 4 byte instruction into two adds which are both 2 byte
938 ;; instructions. There are two cases: one where we are adding a
939 ;; constant plus a register to another register, and one where we are
940 ;; simply adding a constant to a register.
941
942 (define_split
943 [(set (match_operand:DI 0 "register_operand" "")
944 (plus:DI (match_dup 0)
945 (match_operand:DI 1 "const_int_operand" "")))]
946 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
947 && GET_CODE (operands[0]) == REG
948 && M16_REG_P (REGNO (operands[0]))
949 && GET_CODE (operands[1]) == CONST_INT
950 && ((INTVAL (operands[1]) > 0xf
951 && INTVAL (operands[1]) <= 0xf + 0xf)
952 || (INTVAL (operands[1]) < - 0x10
953 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
954 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
955 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
956 "
957 {
958 HOST_WIDE_INT val = INTVAL (operands[1]);
959
960 if (val >= 0)
961 {
962 operands[1] = GEN_INT (0xf);
963 operands[2] = GEN_INT (val - 0xf);
964 }
965 else
966 {
967 operands[1] = GEN_INT (- 0x10);
968 operands[2] = GEN_INT (val + 0x10);
969 }
970 }")
971
972 (define_split
973 [(set (match_operand:DI 0 "register_operand" "")
974 (plus:DI (match_operand:DI 1 "register_operand" "")
975 (match_operand:DI 2 "const_int_operand" "")))]
976 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
977 && GET_CODE (operands[0]) == REG
978 && M16_REG_P (REGNO (operands[0]))
979 && GET_CODE (operands[1]) == REG
980 && M16_REG_P (REGNO (operands[1]))
981 && REGNO (operands[0]) != REGNO (operands[1])
982 && GET_CODE (operands[2]) == CONST_INT
983 && ((INTVAL (operands[2]) > 0x7
984 && INTVAL (operands[2]) <= 0x7 + 0xf)
985 || (INTVAL (operands[2]) < - 0x8
986 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
987 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
988 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
989 "
990 {
991 HOST_WIDE_INT val = INTVAL (operands[2]);
992
993 if (val >= 0)
994 {
995 operands[2] = GEN_INT (0x7);
996 operands[3] = GEN_INT (val - 0x7);
997 }
998 else
999 {
1000 operands[2] = GEN_INT (- 0x8);
1001 operands[3] = GEN_INT (val + 0x8);
1002 }
1003 }")
1004
1005 (define_insn "addsi3_internal_2"
1006 [(set (match_operand:DI 0 "register_operand" "=d")
1007 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1008 (match_operand:SI 2 "arith_operand" "dI"))))]
1009 "TARGET_64BIT
1010 && !TARGET_MIPS16
1011 && (TARGET_GAS
1012 || GET_CODE (operands[2]) != CONST_INT
1013 || INTVAL (operands[2]) != -32768)"
1014 "*
1015 {
1016 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1017 ? \"subu\\t%0,%z1,%n2\"
1018 : \"addu\\t%0,%z1,%2\";
1019 }"
1020 [(set_attr "type" "arith")
1021 (set_attr "mode" "SI")])
1022
1023 (define_insn ""
1024 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1025 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1026 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1027 "TARGET_MIPS16 && TARGET_64BIT"
1028 "*
1029 {
1030 if (REGNO (operands[0]) == REGNO (operands[1]))
1031 return \"addu\\t%0,%2\";
1032 return \"addu\\t%0,%1,%2\";
1033 }"
1034 [(set_attr "type" "arith")
1035 (set_attr "mode" "SI")
1036 (set_attr_alternative "length"
1037 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1038 (const_int 4)
1039 (const_int 8))
1040 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1041 (const_int 4)
1042 (const_int 8))
1043 (const_int 4)])])
1044
1045 \f
1046 ;;
1047 ;; ....................
1048 ;;
1049 ;; SUBTRACTION
1050 ;;
1051 ;; ....................
1052 ;;
1053
1054 (define_insn "subdf3"
1055 [(set (match_operand:DF 0 "register_operand" "=f")
1056 (minus:DF (match_operand:DF 1 "register_operand" "f")
1057 (match_operand:DF 2 "register_operand" "f")))]
1058 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1059 "sub.d\\t%0,%1,%2"
1060 [(set_attr "type" "fadd")
1061 (set_attr "mode" "DF")])
1062
1063 (define_insn "subsf3"
1064 [(set (match_operand:SF 0 "register_operand" "=f")
1065 (minus:SF (match_operand:SF 1 "register_operand" "f")
1066 (match_operand:SF 2 "register_operand" "f")))]
1067 "TARGET_HARD_FLOAT"
1068 "sub.s\\t%0,%1,%2"
1069 [(set_attr "type" "fadd")
1070 (set_attr "mode" "SF")])
1071
1072 (define_expand "subsi3"
1073 [(set (match_operand:SI 0 "register_operand" "=d")
1074 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1075 (match_operand:SI 2 "arith_operand" "dI")))]
1076 ""
1077 "
1078 {
1079 if (GET_CODE (operands[2]) == CONST_INT
1080 && (INTVAL (operands[2]) == -32768
1081 || (TARGET_MIPS16
1082 && INTVAL (operands[2]) == -0x4000)))
1083 operands[2] = force_reg (SImode, operands[2]);
1084 }")
1085
1086 (define_insn "subsi3_internal"
1087 [(set (match_operand:SI 0 "register_operand" "=d")
1088 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1089 (match_operand:SI 2 "arith_operand" "dI")))]
1090 "!TARGET_MIPS16
1091 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1092 "subu\\t%0,%z1,%2"
1093 [(set_attr "type" "arith")
1094 (set_attr "mode" "SI")])
1095
1096 ;; For the mips16, we need to recognize stack pointer subtractions
1097 ;; explicitly, since we don't have a constraint for $sp. These insns
1098 ;; will be generated by the save_restore_insns functions.
1099
1100 (define_insn ""
1101 [(set (reg:SI 29)
1102 (minus:SI (reg:SI 29)
1103 (match_operand:SI 0 "small_int" "I")))]
1104 "TARGET_MIPS16
1105 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1106 "addu\\t%$,%$,%n0"
1107 [(set_attr "type" "arith")
1108 (set_attr "mode" "SI")
1109 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1110 (const_int 4)
1111 (const_int 8)))])
1112
1113 (define_insn ""
1114 [(set (match_operand:SI 0 "register_operand" "=d")
1115 (minus:SI (reg:SI 29)
1116 (match_operand:SI 1 "small_int" "I")))]
1117 "TARGET_MIPS16
1118 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1119 "addu\\t%0,%$,%n1"
1120 [(set_attr "type" "arith")
1121 (set_attr "mode" "SI")
1122 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1123 (const_int 4)
1124 (const_int 8)))])
1125
1126
1127 (define_insn ""
1128 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1129 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1130 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1131 "TARGET_MIPS16
1132 && (GET_CODE (operands[2]) != CONST_INT
1133 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1134 "*
1135 {
1136 if (REGNO (operands[0]) == REGNO (operands[1]))
1137 return \"subu\\t%0,%2\";
1138 return \"subu\\t%0,%1,%2\";
1139 }"
1140 [(set_attr "type" "arith")
1141 (set_attr "mode" "SI")
1142 (set_attr_alternative "length"
1143 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1144 (const_int 4)
1145 (const_int 8))
1146 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1147 (const_int 4)
1148 (const_int 8))
1149 (const_int 4)])])
1150
1151 ;; On the mips16, we can sometimes split an subtract of a constant
1152 ;; which is a 4 byte instruction into two adds which are both 2 byte
1153 ;; instructions. There are two cases: one where we are setting a
1154 ;; register to a register minus a constant, and one where we are
1155 ;; simply subtracting a constant from a register.
1156
1157 (define_split
1158 [(set (match_operand:SI 0 "register_operand" "")
1159 (minus:SI (match_dup 0)
1160 (match_operand:SI 1 "const_int_operand" "")))]
1161 "TARGET_MIPS16 && reload_completed
1162 && GET_CODE (operands[0]) == REG
1163 && M16_REG_P (REGNO (operands[0]))
1164 && GET_CODE (operands[1]) == CONST_INT
1165 && ((INTVAL (operands[1]) > 0x80
1166 && INTVAL (operands[1]) <= 0x80 + 0x80)
1167 || (INTVAL (operands[1]) < - 0x7f
1168 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1169 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1170 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1171 "
1172 {
1173 HOST_WIDE_INT val = INTVAL (operands[1]);
1174
1175 if (val >= 0)
1176 {
1177 operands[1] = GEN_INT (0x80);
1178 operands[2] = GEN_INT (val - 0x80);
1179 }
1180 else
1181 {
1182 operands[1] = GEN_INT (- 0x7f);
1183 operands[2] = GEN_INT (val + 0x7f);
1184 }
1185 }")
1186
1187 (define_split
1188 [(set (match_operand:SI 0 "register_operand" "")
1189 (minus:SI (match_operand:SI 1 "register_operand" "")
1190 (match_operand:SI 2 "const_int_operand" "")))]
1191 "TARGET_MIPS16 && reload_completed
1192 && GET_CODE (operands[0]) == REG
1193 && M16_REG_P (REGNO (operands[0]))
1194 && GET_CODE (operands[1]) == REG
1195 && M16_REG_P (REGNO (operands[1]))
1196 && REGNO (operands[0]) != REGNO (operands[1])
1197 && GET_CODE (operands[2]) == CONST_INT
1198 && ((INTVAL (operands[2]) > 0x8
1199 && INTVAL (operands[2]) <= 0x8 + 0x80)
1200 || (INTVAL (operands[2]) < - 0x7
1201 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1202 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1203 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1204 "
1205 {
1206 HOST_WIDE_INT val = INTVAL (operands[2]);
1207
1208 if (val >= 0)
1209 {
1210 operands[2] = GEN_INT (0x8);
1211 operands[3] = GEN_INT (val - 0x8);
1212 }
1213 else
1214 {
1215 operands[2] = GEN_INT (- 0x7);
1216 operands[3] = GEN_INT (val + 0x7);
1217 }
1218 }")
1219
1220 (define_expand "subdi3"
1221 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1222 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1223 (match_operand:DI 2 "se_register_operand" "d")))
1224 (clobber (match_dup 3))])]
1225 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1226 "
1227 {
1228 if (TARGET_64BIT)
1229 {
1230 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1231 operands[2]));
1232 DONE;
1233 }
1234
1235 operands[3] = gen_reg_rtx (SImode);
1236 }")
1237
1238 (define_insn "subdi3_internal"
1239 [(set (match_operand:DI 0 "register_operand" "=d")
1240 (minus:DI (match_operand:DI 1 "register_operand" "d")
1241 (match_operand:DI 2 "register_operand" "d")))
1242 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1243 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1244 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1245 [(set_attr "type" "darith")
1246 (set_attr "mode" "DI")
1247 (set_attr "length" "16")])
1248
1249 (define_split
1250 [(set (match_operand:DI 0 "register_operand" "")
1251 (minus:DI (match_operand:DI 1 "register_operand" "")
1252 (match_operand:DI 2 "register_operand" "")))
1253 (clobber (match_operand:SI 3 "register_operand" ""))]
1254 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1255 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1256 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1257 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1258 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1259
1260 [(set (match_dup 3)
1261 (ltu:SI (subreg:SI (match_dup 1) 0)
1262 (subreg:SI (match_dup 2) 0)))
1263
1264 (set (subreg:SI (match_dup 0) 0)
1265 (minus:SI (subreg:SI (match_dup 1) 0)
1266 (subreg:SI (match_dup 2) 0)))
1267
1268 (set (subreg:SI (match_dup 0) 1)
1269 (minus:SI (subreg:SI (match_dup 1) 1)
1270 (subreg:SI (match_dup 2) 1)))
1271
1272 (set (subreg:SI (match_dup 0) 1)
1273 (minus:SI (subreg:SI (match_dup 0) 1)
1274 (match_dup 3)))]
1275 "")
1276
1277 (define_split
1278 [(set (match_operand:DI 0 "register_operand" "")
1279 (minus:DI (match_operand:DI 1 "register_operand" "")
1280 (match_operand:DI 2 "register_operand" "")))
1281 (clobber (match_operand:SI 3 "register_operand" ""))]
1282 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1283 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1284 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1285 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1286 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1287
1288 [(set (match_dup 3)
1289 (ltu:SI (subreg:SI (match_dup 1) 1)
1290 (subreg:SI (match_dup 2) 1)))
1291
1292 (set (subreg:SI (match_dup 0) 1)
1293 (minus:SI (subreg:SI (match_dup 1) 1)
1294 (subreg:SI (match_dup 2) 1)))
1295
1296 (set (subreg:SI (match_dup 0) 0)
1297 (minus:SI (subreg:SI (match_dup 1) 0)
1298 (subreg:SI (match_dup 2) 0)))
1299
1300 (set (subreg:SI (match_dup 0) 0)
1301 (minus:SI (subreg:SI (match_dup 0) 0)
1302 (match_dup 3)))]
1303 "")
1304
1305 (define_insn "subdi3_internal_2"
1306 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1307 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1308 (match_operand:DI 2 "small_int" "P,J,N")))
1309 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1310 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1311 && INTVAL (operands[2]) != -32768"
1312 "@
1313 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1314 move\\t%L0,%L1\;move\\t%M0,%M1
1315 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1316 [(set_attr "type" "darith")
1317 (set_attr "mode" "DI")
1318 (set_attr "length" "12,8,16")])
1319
1320 (define_split
1321 [(set (match_operand:DI 0 "register_operand" "")
1322 (minus:DI (match_operand:DI 1 "register_operand" "")
1323 (match_operand:DI 2 "small_int" "")))
1324 (clobber (match_operand:SI 3 "register_operand" ""))]
1325 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1326 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1327 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1328 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1329 && INTVAL (operands[2]) > 0"
1330
1331 [(set (match_dup 3)
1332 (ltu:SI (subreg:SI (match_dup 1) 0)
1333 (match_dup 2)))
1334
1335 (set (subreg:SI (match_dup 0) 0)
1336 (minus:SI (subreg:SI (match_dup 1) 0)
1337 (match_dup 2)))
1338
1339 (set (subreg:SI (match_dup 0) 1)
1340 (minus:SI (subreg:SI (match_dup 1) 1)
1341 (match_dup 3)))]
1342 "")
1343
1344 (define_split
1345 [(set (match_operand:DI 0 "register_operand" "")
1346 (minus:DI (match_operand:DI 1 "register_operand" "")
1347 (match_operand:DI 2 "small_int" "")))
1348 (clobber (match_operand:SI 3 "register_operand" ""))]
1349 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1350 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1351 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1352 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1353 && INTVAL (operands[2]) > 0"
1354
1355 [(set (match_dup 3)
1356 (ltu:SI (subreg:SI (match_dup 1) 1)
1357 (match_dup 2)))
1358
1359 (set (subreg:SI (match_dup 0) 1)
1360 (minus:SI (subreg:SI (match_dup 1) 1)
1361 (match_dup 2)))
1362
1363 (set (subreg:SI (match_dup 0) 0)
1364 (minus:SI (subreg:SI (match_dup 1) 0)
1365 (match_dup 3)))]
1366 "")
1367
1368 (define_insn "subdi3_internal_3"
1369 [(set (match_operand:DI 0 "register_operand" "=d")
1370 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1371 (match_operand:DI 2 "se_arith_operand" "dI")))]
1372 "TARGET_64BIT && !TARGET_MIPS16
1373 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1374 "*
1375 {
1376 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1377 ? \"daddu\\t%0,%z1,%n2\"
1378 : \"dsubu\\t%0,%z1,%2\";
1379 }"
1380 [(set_attr "type" "darith")
1381 (set_attr "mode" "DI")])
1382
1383 ;; For the mips16, we need to recognize stack pointer subtractions
1384 ;; explicitly, since we don't have a constraint for $sp. These insns
1385 ;; will be generated by the save_restore_insns functions.
1386
1387 (define_insn ""
1388 [(set (reg:DI 29)
1389 (minus:DI (reg:DI 29)
1390 (match_operand:DI 0 "small_int" "I")))]
1391 "TARGET_MIPS16
1392 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1393 "daddu\\t%$,%$,%n0"
1394 [(set_attr "type" "arith")
1395 (set_attr "mode" "DI")
1396 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1397 (const_int 4)
1398 (const_int 8)))])
1399
1400 (define_insn ""
1401 [(set (match_operand:DI 0 "register_operand" "=d")
1402 (minus:DI (reg:DI 29)
1403 (match_operand:DI 1 "small_int" "I")))]
1404 "TARGET_MIPS16
1405 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1406 "daddu\\t%0,%$,%n1"
1407 [(set_attr "type" "arith")
1408 (set_attr "mode" "DI")
1409 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1410 (const_int 4)
1411 (const_int 8)))])
1412
1413 (define_insn ""
1414 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1415 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1416 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1417 "TARGET_MIPS16
1418 && (GET_CODE (operands[2]) != CONST_INT
1419 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1420 "*
1421 {
1422 if (REGNO (operands[0]) == REGNO (operands[1]))
1423 return \"dsubu\\t%0,%2\";
1424 return \"dsubu\\t%0,%1,%2\";
1425 }"
1426 [(set_attr "type" "arith")
1427 (set_attr "mode" "DI")
1428 (set_attr_alternative "length"
1429 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1430 (const_int 4)
1431 (const_int 8))
1432 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1433 (const_int 4)
1434 (const_int 8))
1435 (const_int 4)])])
1436
1437 ;; On the mips16, we can sometimes split an add of a constant which is
1438 ;; a 4 byte instruction into two adds which are both 2 byte
1439 ;; instructions. There are two cases: one where we are adding a
1440 ;; constant plus a register to another register, and one where we are
1441 ;; simply adding a constant to a register.
1442
1443 (define_split
1444 [(set (match_operand:DI 0 "register_operand" "")
1445 (minus:DI (match_dup 0)
1446 (match_operand:DI 1 "const_int_operand" "")))]
1447 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1448 && GET_CODE (operands[0]) == REG
1449 && M16_REG_P (REGNO (operands[0]))
1450 && GET_CODE (operands[1]) == CONST_INT
1451 && ((INTVAL (operands[1]) > 0x10
1452 && INTVAL (operands[1]) <= 0x10 + 0x10)
1453 || (INTVAL (operands[1]) < - 0xf
1454 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1455 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1456 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1457 "
1458 {
1459 HOST_WIDE_INT val = INTVAL (operands[1]);
1460
1461 if (val >= 0)
1462 {
1463 operands[1] = GEN_INT (0xf);
1464 operands[2] = GEN_INT (val - 0xf);
1465 }
1466 else
1467 {
1468 operands[1] = GEN_INT (- 0x10);
1469 operands[2] = GEN_INT (val + 0x10);
1470 }
1471 }")
1472
1473 (define_split
1474 [(set (match_operand:DI 0 "register_operand" "")
1475 (minus:DI (match_operand:DI 1 "register_operand" "")
1476 (match_operand:DI 2 "const_int_operand" "")))]
1477 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1478 && GET_CODE (operands[0]) == REG
1479 && M16_REG_P (REGNO (operands[0]))
1480 && GET_CODE (operands[1]) == REG
1481 && M16_REG_P (REGNO (operands[1]))
1482 && REGNO (operands[0]) != REGNO (operands[1])
1483 && GET_CODE (operands[2]) == CONST_INT
1484 && ((INTVAL (operands[2]) > 0x8
1485 && INTVAL (operands[2]) <= 0x8 + 0x10)
1486 || (INTVAL (operands[2]) < - 0x7
1487 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1488 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1489 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1490 "
1491 {
1492 HOST_WIDE_INT val = INTVAL (operands[2]);
1493
1494 if (val >= 0)
1495 {
1496 operands[2] = GEN_INT (0x8);
1497 operands[3] = GEN_INT (val - 0x8);
1498 }
1499 else
1500 {
1501 operands[2] = GEN_INT (- 0x7);
1502 operands[3] = GEN_INT (val + 0x7);
1503 }
1504 }")
1505
1506 (define_insn "subsi3_internal_2"
1507 [(set (match_operand:DI 0 "register_operand" "=d")
1508 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1509 (match_operand:SI 2 "arith_operand" "dI"))))]
1510 "TARGET_64BIT && !TARGET_MIPS16
1511 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1512 "*
1513 {
1514 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1515 ? \"addu\\t%0,%z1,%n2\"
1516 : \"subu\\t%0,%z1,%2\";
1517 }"
1518 [(set_attr "type" "arith")
1519 (set_attr "mode" "DI")])
1520
1521 (define_insn ""
1522 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1523 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1524 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1525 "TARGET_64BIT && TARGET_MIPS16
1526 && (GET_CODE (operands[2]) != CONST_INT
1527 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1528 "*
1529 {
1530 if (REGNO (operands[0]) == REGNO (operands[1]))
1531 return \"subu\\t%0,%2\";
1532 return \"subu\\t%0,%1,%2\";
1533 }"
1534 [(set_attr "type" "arith")
1535 (set_attr "mode" "SI")
1536 (set_attr_alternative "length"
1537 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1538 (const_int 4)
1539 (const_int 8))
1540 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1541 (const_int 4)
1542 (const_int 8))
1543 (const_int 4)])])
1544
1545
1546 \f
1547 ;;
1548 ;; ....................
1549 ;;
1550 ;; MULTIPLICATION
1551 ;;
1552 ;; ....................
1553 ;;
1554
1555 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1556 ;; operands may corrupt immediately following multiplies. This is a
1557 ;; simple fix to insert NOPs.
1558
1559 (define_expand "muldf3"
1560 [(set (match_operand:DF 0 "register_operand" "=f")
1561 (mult:DF (match_operand:DF 1 "register_operand" "f")
1562 (match_operand:DF 2 "register_operand" "f")))]
1563 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1564 "
1565 {
1566 if (mips_cpu != PROCESSOR_R4300)
1567 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1568 else
1569 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1570 DONE;
1571 }")
1572
1573 (define_insn "muldf3_internal"
1574 [(set (match_operand:DF 0 "register_operand" "=f")
1575 (mult:DF (match_operand:DF 1 "register_operand" "f")
1576 (match_operand:DF 2 "register_operand" "f")))]
1577 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
1578 "mul.d\\t%0,%1,%2"
1579 [(set_attr "type" "fmul")
1580 (set_attr "mode" "DF")])
1581
1582 (define_insn "muldf3_r4300"
1583 [(set (match_operand:DF 0 "register_operand" "=f")
1584 (mult:DF (match_operand:DF 1 "register_operand" "f")
1585 (match_operand:DF 2 "register_operand" "f")))]
1586 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
1587 "*
1588 {
1589 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1590 if (TARGET_4300_MUL_FIX)
1591 output_asm_insn (\"nop\", operands);
1592 return \"\";
1593 }"
1594 [(set_attr "type" "fmul")
1595 (set_attr "mode" "DF")
1596 (set_attr "length" "8")]) ;; mul.d + nop
1597
1598 (define_expand "mulsf3"
1599 [(set (match_operand:SF 0 "register_operand" "=f")
1600 (mult:SF (match_operand:SF 1 "register_operand" "f")
1601 (match_operand:SF 2 "register_operand" "f")))]
1602 "TARGET_HARD_FLOAT"
1603 "
1604 {
1605 if (mips_cpu != PROCESSOR_R4300)
1606 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1607 else
1608 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1609 DONE;
1610 }")
1611
1612 (define_insn "mulsf3_internal"
1613 [(set (match_operand:SF 0 "register_operand" "=f")
1614 (mult:SF (match_operand:SF 1 "register_operand" "f")
1615 (match_operand:SF 2 "register_operand" "f")))]
1616 "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
1617 "mul.s\\t%0,%1,%2"
1618 [(set_attr "type" "fmul")
1619 (set_attr "mode" "SF")])
1620
1621 (define_insn "mulsf3_r4300"
1622 [(set (match_operand:SF 0 "register_operand" "=f")
1623 (mult:SF (match_operand:SF 1 "register_operand" "f")
1624 (match_operand:SF 2 "register_operand" "f")))]
1625 "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1626 "*
1627 {
1628 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1629 if (TARGET_4300_MUL_FIX)
1630 output_asm_insn (\"nop\", operands);
1631 return \"\";
1632 }"
1633 [(set_attr "type" "fmul")
1634 (set_attr "mode" "SF")
1635 (set_attr "length" "8")]) ;; mul.s + nop
1636
1637
1638 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1639 ;; a multiply is in progress, it may give an incorrect result. Avoid
1640 ;; this by keeping the mflo with the mult on the R4000.
1641
1642 (define_expand "mulsi3"
1643 [(set (match_operand:SI 0 "register_operand" "=l")
1644 (mult:SI (match_operand:SI 1 "register_operand" "d")
1645 (match_operand:SI 2 "register_operand" "d")))
1646 (clobber (match_scratch:SI 3 "=h"))
1647 (clobber (match_scratch:SI 4 "=a"))]
1648 ""
1649 "
1650 {
1651 if (HAVE_mulsi3_mult3)
1652 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1653 else if (mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16)
1654 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1655 else
1656 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1657 DONE;
1658 }")
1659
1660 (define_insn "mulsi3_mult3"
1661 [(set (match_operand:SI 0 "register_operand" "=d,l")
1662 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1663 (match_operand:SI 2 "register_operand" "d,d")))
1664 (clobber (match_scratch:SI 3 "=h,h"))
1665 (clobber (match_scratch:SI 4 "=l,X"))
1666 (clobber (match_scratch:SI 5 "=a,a"))]
1667 "GENERATE_MULT3
1668 || TARGET_MAD"
1669 "*
1670 {
1671 if (which_alternative == 1)
1672 return \"mult\\t%1,%2\";
1673 if (TARGET_MAD)
1674 return \"mul\\t%0,%1,%2\";
1675 return \"mult\\t%0,%1,%2\";
1676 }"
1677 [(set_attr "type" "imul")
1678 (set_attr "mode" "SI")])
1679
1680 (define_insn "mulsi3_internal"
1681 [(set (match_operand:SI 0 "register_operand" "=l")
1682 (mult:SI (match_operand:SI 1 "register_operand" "d")
1683 (match_operand:SI 2 "register_operand" "d")))
1684 (clobber (match_scratch:SI 3 "=h"))
1685 (clobber (match_scratch:SI 4 "=a"))]
1686 "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16"
1687 "mult\\t%1,%2"
1688 [(set_attr "type" "imul")
1689 (set_attr "mode" "SI")])
1690
1691 (define_insn "mulsi3_r4000"
1692 [(set (match_operand:SI 0 "register_operand" "=d")
1693 (mult:SI (match_operand:SI 1 "register_operand" "d")
1694 (match_operand:SI 2 "register_operand" "d")))
1695 (clobber (match_scratch:SI 3 "=h"))
1696 (clobber (match_scratch:SI 4 "=l"))
1697 (clobber (match_scratch:SI 5 "=a"))]
1698 "mips_cpu == PROCESSOR_R4000 && !TARGET_MIPS16"
1699 "*
1700 {
1701 rtx xoperands[10];
1702
1703 xoperands[0] = operands[0];
1704 xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1705
1706 output_asm_insn (\"mult\\t%1,%2\", operands);
1707 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1708 return \"\";
1709 }"
1710 [(set_attr "type" "imul")
1711 (set_attr "mode" "SI")
1712 (set_attr "length" "12")]) ;; mult + mflo + delay
1713
1714 ;; Multiply-accumulate patterns
1715
1716 ;; For processors that can copy the output to a general register:
1717 ;;
1718 ;; The all-d alternative is needed because the combiner will find this
1719 ;; pattern and then register alloc/reload will move registers around to
1720 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1721 ;;
1722 ;; The last alternative should be made slightly less desirable, but adding
1723 ;; "?" to the constraint is too strong, and causes values to be loaded into
1724 ;; LO even when that's more costly. For now, using "*d" mostly does the
1725 ;; trick.
1726 (define_insn "*mul_acc_si"
1727 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1728 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1729 (match_operand:SI 2 "register_operand" "d,d,d"))
1730 (match_operand:SI 3 "register_operand" "0,l,*d")))
1731 (clobber (match_scratch:SI 4 "=h,h,h"))
1732 (clobber (match_scratch:SI 5 "=X,3,l"))
1733 (clobber (match_scratch:SI 6 "=a,a,a"))
1734 (clobber (match_scratch:SI 7 "=X,X,d"))]
1735 "TARGET_MIPS3900
1736 && !TARGET_MIPS16"
1737 "*
1738 {
1739 static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1740 if (which_alternative == 2)
1741 return \"#\";
1742 return madd[which_alternative];
1743 }"
1744 [(set_attr "type" "imul,imul,multi")
1745 (set_attr "mode" "SI")
1746 (set_attr "length" "4,4,8")])
1747
1748 ;; Split the above insn if we failed to get LO allocated.
1749 (define_split
1750 [(set (match_operand:SI 0 "register_operand" "")
1751 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1752 (match_operand:SI 2 "register_operand" ""))
1753 (match_operand:SI 3 "register_operand" "")))
1754 (clobber (match_scratch:SI 4 ""))
1755 (clobber (match_scratch:SI 5 ""))
1756 (clobber (match_scratch:SI 6 ""))
1757 (clobber (match_scratch:SI 7 ""))]
1758 "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[3]))"
1759 [(parallel [(set (match_dup 7)
1760 (mult:SI (match_dup 1) (match_dup 2)))
1761 (clobber (match_dup 4))
1762 (clobber (match_dup 5))
1763 (clobber (match_dup 6))])
1764 (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1765 "")
1766
1767 (define_split
1768 [(set (match_operand:SI 0 "register_operand" "")
1769 (minus:SI (match_operand:SI 1 "register_operand" "")
1770 (mult:SI (match_operand:SI 2 "register_operand" "")
1771 (match_operand:SI 3 "register_operand" ""))))
1772 (clobber (match_scratch:SI 4 ""))
1773 (clobber (match_scratch:SI 5 ""))
1774 (clobber (match_scratch:SI 6 ""))
1775 (clobber (match_scratch:SI 7 ""))]
1776 "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[1]))"
1777 [(parallel [(set (match_dup 7)
1778 (mult:SI (match_dup 2) (match_dup 3)))
1779 (clobber (match_dup 4))
1780 (clobber (match_dup 5))
1781 (clobber (match_dup 6))])
1782 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1783 "")
1784
1785 (define_expand "muldi3"
1786 [(set (match_operand:DI 0 "register_operand" "=l")
1787 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1788 (match_operand:DI 2 "register_operand" "d")))
1789 (clobber (match_scratch:DI 3 "=h"))
1790 (clobber (match_scratch:DI 4 "=a"))]
1791 "TARGET_64BIT"
1792
1793 "
1794 {
1795 if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)
1796 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1797 else
1798 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1799 DONE;
1800 }")
1801
1802 ;; Don't accept both operands using se_register_operand, because if
1803 ;; both operands are sign extended we would prefer to use mult in the
1804 ;; mulsidi3 pattern. Commutativity should permit either operand to be
1805 ;; sign extended.
1806
1807 (define_insn "muldi3_internal"
1808 [(set (match_operand:DI 0 "register_operand" "=l")
1809 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1810 (match_operand:DI 2 "register_operand" "d")))
1811 (clobber (match_scratch:DI 3 "=h"))
1812 (clobber (match_scratch:DI 4 "=a"))]
1813 "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16"
1814 "dmult\\t%1,%2"
1815 [(set_attr "type" "imul")
1816 (set_attr "mode" "DI")])
1817
1818 (define_insn "muldi3_internal2"
1819 [(set (match_operand:DI 0 "register_operand" "=d")
1820 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1821 (match_operand:DI 2 "register_operand" "d")))
1822 (clobber (match_scratch:DI 3 "=h"))
1823 (clobber (match_scratch:DI 4 "=l"))
1824 (clobber (match_scratch:DI 5 "=a"))]
1825 "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)"
1826 "*
1827 {
1828 if (GENERATE_MULT3)
1829 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1830 else
1831 {
1832 rtx xoperands[10];
1833
1834 xoperands[0] = operands[0];
1835 xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1836
1837 output_asm_insn (\"dmult\\t%1,%2\", operands);
1838 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1839 }
1840 return \"\";
1841 }"
1842 [(set_attr "type" "imul")
1843 (set_attr "mode" "DI")
1844 (set (attr "length")
1845 (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1846 (const_int 4)
1847 (const_int 12)))]) ;; mult + mflo + delay
1848
1849 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1850
1851 (define_expand "mulsidi3"
1852 [(set (match_operand:DI 0 "register_operand" "=x")
1853 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1854 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1855 ""
1856 "
1857 {
1858 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1859 if (TARGET_64BIT)
1860 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1861 dummy, dummy));
1862 else
1863 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1864 dummy, dummy));
1865 DONE;
1866 }")
1867
1868 (define_expand "umulsidi3"
1869 [(set (match_operand:DI 0 "register_operand" "=x")
1870 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1871 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1872 ""
1873 "
1874 {
1875 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1876 if (TARGET_64BIT)
1877 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1878 dummy, dummy));
1879 else
1880 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1881 dummy, dummy));
1882 DONE;
1883 }")
1884
1885 (define_insn "mulsidi3_internal"
1886 [(set (match_operand:DI 0 "register_operand" "=x")
1887 (mult:DI (match_operator:DI 3 "extend_operator"
1888 [(match_operand:SI 1 "register_operand" "d")])
1889 (match_operator:DI 4 "extend_operator"
1890 [(match_operand:SI 2 "register_operand" "d")])))
1891 (clobber (match_scratch:SI 5 "=a"))]
1892 "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1893 "*
1894 {
1895 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1896 return \"mult\\t%1,%2\";
1897 return \"multu\\t%1,%2\";
1898 }"
1899 [(set_attr "type" "imul")
1900 (set_attr "mode" "SI")])
1901
1902 (define_insn "mulsidi3_64bit"
1903 [(set (match_operand:DI 0 "register_operand" "=a")
1904 (mult:DI (match_operator:DI 3 "extend_operator"
1905 [(match_operand:SI 1 "register_operand" "d")])
1906 (match_operator:DI 4 "extend_operator"
1907 [(match_operand:SI 2 "register_operand" "d")])))
1908 (clobber (match_scratch:DI 5 "=l"))
1909 (clobber (match_scratch:DI 6 "=h"))]
1910 "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1911 "*
1912 {
1913 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1914 return \"mult\\t%1,%2\";
1915 return \"multu\\t%1,%2\";
1916 }"
1917 [(set_attr "type" "imul")
1918 (set_attr "mode" "SI")])
1919
1920 ;; _highpart patterns
1921 (define_expand "smulsi3_highpart"
1922 [(set (match_operand:SI 0 "register_operand" "=h")
1923 (truncate:SI
1924 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1925 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1926 (const_int 32))))]
1927 ""
1928 "
1929 {
1930 rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1931 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
1932 #ifndef NO_MD_PROTOTYPES
1933 rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
1934 #else
1935 rtx (*genfn) ();
1936 #endif
1937 genfn = gen_xmulsi3_highpart_internal;
1938 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1939 dummy, dummy2));
1940 DONE;
1941 }")
1942
1943 (define_expand "umulsi3_highpart"
1944 [(set (match_operand:SI 0 "register_operand" "=h")
1945 (truncate:SI
1946 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1947 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1948 (const_int 32))))]
1949 ""
1950 "
1951 {
1952 rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1953 rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
1954 #ifndef NO_MD_PROTOTYPES
1955 rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
1956 #else
1957 rtx (*genfn) ();
1958 #endif
1959 genfn = gen_xmulsi3_highpart_internal;
1960 emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1961 dummy, dummy2));
1962 DONE;
1963 }")
1964
1965 (define_insn "xmulsi3_highpart_internal"
1966 [(set (match_operand:SI 0 "register_operand" "=h")
1967 (truncate:SI
1968 (match_operator:DI 5 "highpart_shift_operator"
1969 [(mult:DI (match_operator:DI 3 "extend_operator"
1970 [(match_operand:SI 1 "register_operand" "d")])
1971 (match_operator:DI 4 "extend_operator"
1972 [(match_operand:SI 2 "register_operand" "d")]))
1973 (const_int 32)])))
1974 (clobber (match_scratch:SI 6 "=l"))
1975 (clobber (match_scratch:SI 7 "=a"))]
1976 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
1977 "*
1978 {
1979 if (GET_CODE (operands[3]) == SIGN_EXTEND)
1980 return \"mult\\t%1,%2\";
1981 else
1982 return \"multu\\t%1,%2\";
1983 }"
1984 [(set_attr "type" "imul")
1985 (set_attr "mode" "SI")])
1986
1987 (define_insn "smuldi3_highpart"
1988 [(set (match_operand:DI 0 "register_operand" "=h")
1989 (truncate:DI
1990 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1991 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1992 (const_int 64))))
1993 (clobber (match_scratch:DI 3 "=l"))
1994 (clobber (match_scratch:DI 4 "=a"))]
1995 "TARGET_64BIT"
1996 "dmult\\t%1,%2"
1997 [(set_attr "type" "imul")
1998 (set_attr "mode" "DI")])
1999
2000 (define_insn "umuldi3_highpart"
2001 [(set (match_operand:DI 0 "register_operand" "=h")
2002 (truncate:DI
2003 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2004 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2005 (const_int 64))))
2006 (clobber (match_scratch:DI 3 "=l"))
2007 (clobber (match_scratch:DI 4 "=a"))]
2008 "TARGET_64BIT"
2009 "dmultu\\t%1,%2"
2010 [(set_attr "type" "imul")
2011 (set_attr "mode" "DI")])
2012
2013 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2014 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2015
2016 (define_insn "madsi"
2017 [(set (match_operand:SI 0 "register_operand" "+l")
2018 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2019 (match_operand:SI 2 "register_operand" "d"))
2020 (match_dup 0)))
2021 (clobber (match_scratch:SI 3 "=h"))
2022 (clobber (match_scratch:SI 4 "=a"))]
2023 "TARGET_MAD"
2024 "mad\\t%1,%2"
2025 [(set_attr "type" "imul")
2026 (set_attr "mode" "SI")])
2027
2028 (define_insn "*mul_acc_di"
2029 [(set (match_operand:DI 0 "register_operand" "+x")
2030 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2031 [(match_operand:SI 1 "register_operand" "d")])
2032 (match_operator:DI 4 "extend_operator"
2033 [(match_operand:SI 2 "register_operand" "d")]))
2034 (match_dup 0)))
2035 (clobber (match_scratch:SI 5 "=a"))]
2036 "TARGET_MAD
2037 && ! TARGET_64BIT
2038 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2039 "*
2040 {
2041 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2042 return \"mad\\t%1,%2\";
2043 else
2044 return \"madu\\t%1,%2\";
2045 }"
2046 [(set_attr "type" "imul")
2047 (set_attr "mode" "SI")])
2048
2049 (define_insn "*mul_acc_64bit_di"
2050 [(set (match_operand:DI 0 "register_operand" "+a")
2051 (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2052 [(match_operand:SI 1 "register_operand" "d")])
2053 (match_operator:DI 4 "extend_operator"
2054 [(match_operand:SI 2 "register_operand" "d")]))
2055 (match_dup 0)))
2056 (clobber (match_scratch:SI 5 "=h"))
2057 (clobber (match_scratch:SI 6 "=l"))]
2058 "TARGET_MAD
2059 && TARGET_64BIT
2060 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2061 "*
2062 {
2063 if (GET_CODE (operands[3]) == SIGN_EXTEND)
2064 return \"mad\\t%1,%2\";
2065 else
2066 return \"madu\\t%1,%2\";
2067 }"
2068 [(set_attr "type" "imul")
2069 (set_attr "mode" "SI")])
2070
2071 ;; Floating point multiply accumulate instructions.
2072
2073 (define_insn ""
2074 [(set (match_operand:DF 0 "register_operand" "=f")
2075 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2076 (match_operand:DF 2 "register_operand" "f"))
2077 (match_operand:DF 3 "register_operand" "f")))]
2078 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2079 "madd.d\\t%0,%3,%1,%2"
2080 [(set_attr "type" "fmadd")
2081 (set_attr "mode" "DF")])
2082
2083 (define_insn ""
2084 [(set (match_operand:SF 0 "register_operand" "=f")
2085 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2086 (match_operand:SF 2 "register_operand" "f"))
2087 (match_operand:SF 3 "register_operand" "f")))]
2088 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2089 "madd.s\\t%0,%3,%1,%2"
2090 [(set_attr "type" "fmadd")
2091 (set_attr "mode" "SF")])
2092
2093 (define_insn ""
2094 [(set (match_operand:DF 0 "register_operand" "=f")
2095 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2096 (match_operand:DF 2 "register_operand" "f"))
2097 (match_operand:DF 3 "register_operand" "f")))]
2098 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2099 "msub.d\\t%0,%3,%1,%2"
2100 [(set_attr "type" "fmadd")
2101 (set_attr "mode" "DF")])
2102
2103 (define_insn ""
2104 [(set (match_operand:SF 0 "register_operand" "=f")
2105 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2106 (match_operand:SF 2 "register_operand" "f"))
2107 (match_operand:SF 3 "register_operand" "f")))]
2108
2109 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2110 "msub.s\\t%0,%3,%1,%2"
2111 [(set_attr "type" "fmadd")
2112 (set_attr "mode" "SF")])
2113
2114 (define_insn ""
2115 [(set (match_operand:DF 0 "register_operand" "=f")
2116 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2117 (match_operand:DF 2 "register_operand" "f"))
2118 (match_operand:DF 3 "register_operand" "f"))))]
2119 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2120 "nmadd.d\\t%0,%3,%1,%2"
2121 [(set_attr "type" "fmadd")
2122 (set_attr "mode" "DF")])
2123
2124 (define_insn ""
2125 [(set (match_operand:SF 0 "register_operand" "=f")
2126 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2127 (match_operand:SF 2 "register_operand" "f"))
2128 (match_operand:SF 3 "register_operand" "f"))))]
2129 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2130 "nmadd.s\\t%0,%3,%1,%2"
2131 [(set_attr "type" "fmadd")
2132 (set_attr "mode" "SF")])
2133
2134 (define_insn ""
2135 [(set (match_operand:DF 0 "register_operand" "=f")
2136 (minus:DF (match_operand:DF 1 "register_operand" "f")
2137 (mult:DF (match_operand:DF 2 "register_operand" "f")
2138 (match_operand:DF 3 "register_operand" "f"))))]
2139 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2140 "nmsub.d\\t%0,%1,%2,%3"
2141 [(set_attr "type" "fmadd")
2142 (set_attr "mode" "DF")])
2143
2144 (define_insn ""
2145 [(set (match_operand:SF 0 "register_operand" "=f")
2146 (minus:SF (match_operand:SF 1 "register_operand" "f")
2147 (mult:SF (match_operand:SF 2 "register_operand" "f")
2148 (match_operand:SF 3 "register_operand" "f"))))]
2149 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2150 "nmsub.s\\t%0,%1,%2,%3"
2151 [(set_attr "type" "fmadd")
2152 (set_attr "mode" "SF")])
2153 \f
2154 ;;
2155 ;; ....................
2156 ;;
2157 ;; DIVISION and REMAINDER
2158 ;;
2159 ;; ....................
2160 ;;
2161
2162 (define_insn "divdf3"
2163 [(set (match_operand:DF 0 "register_operand" "=f")
2164 (div:DF (match_operand:DF 1 "register_operand" "f")
2165 (match_operand:DF 2 "register_operand" "f")))]
2166 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2167 "div.d\\t%0,%1,%2"
2168 [(set_attr "type" "fdiv")
2169 (set_attr "mode" "DF")])
2170
2171 (define_insn "divsf3"
2172 [(set (match_operand:SF 0 "register_operand" "=f")
2173 (div:SF (match_operand:SF 1 "register_operand" "f")
2174 (match_operand:SF 2 "register_operand" "f")))]
2175 "TARGET_HARD_FLOAT"
2176 "div.s\\t%0,%1,%2"
2177 [(set_attr "type" "fdiv")
2178 (set_attr "mode" "SF")])
2179
2180 (define_insn ""
2181 [(set (match_operand:DF 0 "register_operand" "=f")
2182 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2183 (match_operand:DF 2 "register_operand" "f")))]
2184 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2185 "recip.d\\t%0,%2"
2186 [(set_attr "type" "fdiv")
2187 (set_attr "mode" "DF")])
2188
2189 (define_insn ""
2190 [(set (match_operand:SF 0 "register_operand" "=f")
2191 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2192 (match_operand:SF 2 "register_operand" "f")))]
2193 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2194 "recip.s\\t%0,%2"
2195 [(set_attr "type" "fdiv")
2196 (set_attr "mode" "SF")])
2197
2198 ;; If optimizing, prefer the divmod functions over separate div and
2199 ;; mod functions, since this will allow using one instruction for both
2200 ;; the quotient and remainder. At present, the divmod is not moved out
2201 ;; of loops if it is constant within the loop, so allow -mdebugc to
2202 ;; use the old method of doing things.
2203
2204 ;; 64 is the multiply/divide hi register
2205 ;; 65 is the multiply/divide lo register
2206
2207 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2208 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2209 ;; available.
2210
2211 (define_expand "divmodsi4"
2212 [(set (match_operand:SI 0 "register_operand" "=d")
2213 (div:SI (match_operand:SI 1 "register_operand" "d")
2214 (match_operand:SI 2 "register_operand" "d")))
2215 (set (match_operand:SI 3 "register_operand" "=d")
2216 (mod:SI (match_dup 1)
2217 (match_dup 2)))
2218 (clobber (match_scratch:SI 4 "=l"))
2219 (clobber (match_scratch:SI 5 "=h"))
2220 (clobber (match_scratch:SI 6 "=a"))]
2221 "optimize"
2222 "
2223 {
2224 emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2225 operands[3]));
2226 if (!TARGET_NO_CHECK_ZERO_DIV)
2227 {
2228 emit_insn (gen_div_trap (operands[2],
2229 GEN_INT (0),
2230 GEN_INT (0x7)));
2231 }
2232 if (TARGET_CHECK_RANGE_DIV)
2233 {
2234 emit_insn (gen_div_trap (operands[2],
2235 copy_to_mode_reg (SImode, GEN_INT (-1)),
2236 GEN_INT (0x6)));
2237 emit_insn (gen_div_trap (operands[2],
2238 copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2239 GEN_INT (0x6)));
2240 }
2241
2242 DONE;
2243 }")
2244
2245 (define_insn "divmodsi4_internal"
2246 [(set (match_operand:SI 0 "register_operand" "=l")
2247 (div:SI (match_operand:SI 1 "register_operand" "d")
2248 (match_operand:SI 2 "register_operand" "d")))
2249 (set (match_operand:SI 3 "register_operand" "=h")
2250 (mod:SI (match_dup 1)
2251 (match_dup 2)))
2252 (clobber (match_scratch:SI 6 "=a"))]
2253 "optimize"
2254 "div\\t$0,%1,%2"
2255 [(set_attr "type" "idiv")
2256 (set_attr "mode" "SI")])
2257
2258 (define_expand "divmoddi4"
2259 [(set (match_operand:DI 0 "register_operand" "=d")
2260 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2261 (match_operand:DI 2 "se_register_operand" "d")))
2262 (set (match_operand:DI 3 "register_operand" "=d")
2263 (mod:DI (match_dup 1)
2264 (match_dup 2)))
2265 (clobber (match_scratch:DI 4 "=l"))
2266 (clobber (match_scratch:DI 5 "=h"))
2267 (clobber (match_scratch:DI 6 "=a"))]
2268 "TARGET_64BIT && optimize"
2269 "
2270 {
2271 emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2272 operands[3]));
2273 if (!TARGET_NO_CHECK_ZERO_DIV)
2274 {
2275 emit_insn (gen_div_trap (operands[2],
2276 GEN_INT (0),
2277 GEN_INT (0x7)));
2278 }
2279 if (TARGET_CHECK_RANGE_DIV)
2280 {
2281 emit_insn (gen_div_trap (operands[2],
2282 copy_to_mode_reg (DImode, GEN_INT (-1)),
2283 GEN_INT (0x6)));
2284 emit_insn (gen_div_trap (operands[2],
2285 copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2286 GEN_INT (0x6)));
2287 }
2288
2289 DONE;
2290 }")
2291
2292 (define_insn "divmoddi4_internal"
2293 [(set (match_operand:DI 0 "register_operand" "=l")
2294 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2295 (match_operand:DI 2 "se_register_operand" "d")))
2296 (set (match_operand:DI 3 "register_operand" "=h")
2297 (mod:DI (match_dup 1)
2298 (match_dup 2)))
2299 (clobber (match_scratch:DI 6 "=a"))]
2300 "TARGET_64BIT && optimize"
2301 "ddiv\\t$0,%1,%2"
2302 [(set_attr "type" "idiv")
2303 (set_attr "mode" "SI")])
2304
2305 (define_expand "udivmodsi4"
2306 [(set (match_operand:SI 0 "register_operand" "=d")
2307 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2308 (match_operand:SI 2 "register_operand" "d")))
2309 (set (match_operand:SI 3 "register_operand" "=d")
2310 (umod:SI (match_dup 1)
2311 (match_dup 2)))
2312 (clobber (match_scratch:SI 4 "=l"))
2313 (clobber (match_scratch:SI 5 "=h"))
2314 (clobber (match_scratch:SI 6 "=a"))]
2315 "optimize"
2316 "
2317 {
2318 emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2319 operands[3]));
2320 if (!TARGET_NO_CHECK_ZERO_DIV)
2321 {
2322 emit_insn (gen_div_trap (operands[2],
2323 GEN_INT (0),
2324 GEN_INT (0x7)));
2325 }
2326
2327 DONE;
2328 }")
2329
2330 (define_insn "udivmodsi4_internal"
2331 [(set (match_operand:SI 0 "register_operand" "=l")
2332 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2333 (match_operand:SI 2 "register_operand" "d")))
2334 (set (match_operand:SI 3 "register_operand" "=h")
2335 (umod:SI (match_dup 1)
2336 (match_dup 2)))
2337 (clobber (match_scratch:SI 6 "=a"))]
2338 "optimize"
2339 "divu\\t$0,%1,%2"
2340 [(set_attr "type" "idiv")
2341 (set_attr "mode" "SI")])
2342
2343 (define_expand "udivmoddi4"
2344 [(set (match_operand:DI 0 "register_operand" "=d")
2345 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2346 (match_operand:DI 2 "se_register_operand" "d")))
2347 (set (match_operand:DI 3 "register_operand" "=d")
2348 (umod:DI (match_dup 1)
2349 (match_dup 2)))
2350 (clobber (match_scratch:DI 4 "=l"))
2351 (clobber (match_scratch:DI 5 "=h"))
2352 (clobber (match_scratch:DI 6 "=a"))]
2353 "TARGET_64BIT && optimize"
2354 "
2355 {
2356 emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2357 operands[3]));
2358 if (!TARGET_NO_CHECK_ZERO_DIV)
2359 {
2360 emit_insn (gen_div_trap (operands[2],
2361 GEN_INT (0),
2362 GEN_INT (0x7)));
2363 }
2364
2365 DONE;
2366 }")
2367
2368 (define_insn "udivmoddi4_internal"
2369 [(set (match_operand:DI 0 "register_operand" "=l")
2370 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2371 (match_operand:DI 2 "se_register_operand" "d")))
2372 (set (match_operand:DI 3 "register_operand" "=h")
2373 (umod:DI (match_dup 1)
2374 (match_dup 2)))
2375 (clobber (match_scratch:DI 6 "=a"))]
2376 "TARGET_64BIT && optimize"
2377 "ddivu\\t$0,%1,%2"
2378 [(set_attr "type" "idiv")
2379 (set_attr "mode" "SI")])
2380
2381 ;; Division trap
2382
2383 (define_expand "div_trap"
2384 [(trap_if (eq (match_operand 0 "register_operand" "d")
2385 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2386 (match_operand 2 "immediate_operand" ""))]
2387 ""
2388 "
2389 {
2390 if (TARGET_MIPS16)
2391 emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2392 else
2393 emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2394 DONE;
2395 }")
2396
2397 (define_insn "div_trap_normal"
2398 [(trap_if (eq (match_operand 0 "register_operand" "d")
2399 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2400 (match_operand 2 "immediate_operand" ""))]
2401 "!TARGET_MIPS16"
2402 "*
2403 {
2404 rtx link;
2405 int have_dep_anti = 0;
2406
2407 /* For divmod if one division is not needed then we don't need an extra
2408 divide by zero trap, which is anti dependent on previous trap */
2409 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2410
2411 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2412 && GET_CODE (XEXP (link, 0)) == INSN
2413 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2414 && REGNO (operands[1]) == 0)
2415 have_dep_anti = 1;
2416 if (! have_dep_anti)
2417 {
2418 if (GENERATE_BRANCHLIKELY)
2419 {
2420 if (GET_CODE (operands[1]) == CONST_INT)
2421 return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2422 else
2423 return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2424 }
2425 else
2426 {
2427 if (GET_CODE (operands[1]) == CONST_INT)
2428 return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2429 else
2430 return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2431 }
2432 }
2433 return \"\";
2434 }"
2435 [(set_attr "type" "unknown")
2436 (set_attr "length" "12")])
2437
2438
2439 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2440
2441 (define_insn "div_trap_mips16"
2442 [(trap_if (eq (match_operand 0 "register_operand" "d")
2443 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2444 (match_operand 2 "immediate_operand" ""))
2445 (clobber (reg:SI 24))]
2446 "TARGET_MIPS16"
2447 "*
2448 {
2449 rtx link;
2450 int have_dep_anti = 0;
2451
2452 /* For divmod if one division is not needed then we don't need an extra
2453 divide by zero trap, which is anti dependent on previous trap */
2454 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2455
2456 if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2457 && GET_CODE (XEXP (link, 0)) == INSN
2458 && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2459 && REGNO (operands[1]) == 0)
2460 have_dep_anti = 1;
2461 if (! have_dep_anti)
2462 {
2463 /* No branch delay slots on mips16. */
2464 if (GET_CODE (operands[1]) == CONST_INT)
2465 return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2466 else
2467 return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2468 }
2469 return \"\";
2470 }"
2471 [(set_attr "type" "unknown")
2472 (set_attr "length" "12")])
2473
2474 (define_expand "divsi3"
2475 [(set (match_operand:SI 0 "register_operand" "=l")
2476 (div:SI (match_operand:SI 1 "register_operand" "d")
2477 (match_operand:SI 2 "register_operand" "d")))
2478 (clobber (match_scratch:SI 3 "=h"))
2479 (clobber (match_scratch:SI 4 "=a"))]
2480 "!optimize"
2481 "
2482 {
2483 emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2484 if (!TARGET_NO_CHECK_ZERO_DIV)
2485 {
2486 emit_insn (gen_div_trap (operands[2],
2487 GEN_INT (0),
2488 GEN_INT (0x7)));
2489 }
2490 if (TARGET_CHECK_RANGE_DIV)
2491 {
2492 emit_insn (gen_div_trap (operands[2],
2493 copy_to_mode_reg (SImode, GEN_INT (-1)),
2494 GEN_INT (0x6)));
2495 emit_insn (gen_div_trap (operands[2],
2496 copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2497 GEN_INT (0x6)));
2498 }
2499
2500 DONE;
2501 }")
2502
2503 (define_insn "divsi3_internal"
2504 [(set (match_operand:SI 0 "register_operand" "=l")
2505 (div:SI (match_operand:SI 1 "register_operand" "d")
2506 (match_operand:SI 2 "nonmemory_operand" "di")))
2507 (clobber (match_scratch:SI 3 "=h"))
2508 (clobber (match_scratch:SI 4 "=a"))]
2509 "!optimize"
2510 "div\\t$0,%1,%2"
2511 [(set_attr "type" "idiv")
2512 (set_attr "mode" "SI")])
2513
2514 (define_expand "divdi3"
2515 [(set (match_operand:DI 0 "register_operand" "=l")
2516 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2517 (match_operand:DI 2 "se_register_operand" "d")))
2518 (clobber (match_scratch:DI 3 "=h"))
2519 (clobber (match_scratch:DI 4 "=a"))]
2520 "TARGET_64BIT && !optimize"
2521 "
2522 {
2523 emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2524 if (!TARGET_NO_CHECK_ZERO_DIV)
2525 {
2526 emit_insn (gen_div_trap (operands[2],
2527 GEN_INT (0),
2528 GEN_INT (0x7)));
2529 }
2530 if (TARGET_CHECK_RANGE_DIV)
2531 {
2532 emit_insn (gen_div_trap (operands[2],
2533 copy_to_mode_reg (DImode, GEN_INT (-1)),
2534 GEN_INT (0x6)));
2535 emit_insn (gen_div_trap (operands[2],
2536 copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2537 GEN_INT (0x6)));
2538 }
2539
2540 DONE;
2541 }")
2542
2543 (define_insn "divdi3_internal"
2544 [(set (match_operand:DI 0 "register_operand" "=l")
2545 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2546 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2547 (clobber (match_scratch:SI 3 "=h"))
2548 (clobber (match_scratch:SI 4 "=a"))]
2549 "TARGET_64BIT && !optimize"
2550 "ddiv\\t$0,%1,%2"
2551 [(set_attr "type" "idiv")
2552 (set_attr "mode" "DI")])
2553
2554 (define_expand "modsi3"
2555 [(set (match_operand:SI 0 "register_operand" "=h")
2556 (mod:SI (match_operand:SI 1 "register_operand" "d")
2557 (match_operand:SI 2 "register_operand" "d")))
2558 (clobber (match_scratch:SI 3 "=l"))
2559 (clobber (match_scratch:SI 4 "=a"))]
2560 "!optimize"
2561 "
2562 {
2563 emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2564 if (!TARGET_NO_CHECK_ZERO_DIV)
2565 {
2566 emit_insn (gen_div_trap (operands[2],
2567 GEN_INT (0),
2568 GEN_INT (0x7)));
2569 }
2570 if (TARGET_CHECK_RANGE_DIV)
2571 {
2572 emit_insn (gen_div_trap (operands[2],
2573 copy_to_mode_reg (SImode, GEN_INT (-1)),
2574 GEN_INT (0x6)));
2575 emit_insn (gen_div_trap (operands[2],
2576 copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2577 GEN_INT (0x6)));
2578 }
2579
2580 DONE;
2581 }")
2582
2583 (define_insn "modsi3_internal"
2584 [(set (match_operand:SI 0 "register_operand" "=h")
2585 (mod:SI (match_operand:SI 1 "register_operand" "d")
2586 (match_operand:SI 2 "nonmemory_operand" "di")))
2587 (clobber (match_scratch:SI 3 "=l"))
2588 (clobber (match_scratch:SI 4 "=a"))]
2589 "!optimize"
2590 "div\\t$0,%1,%2"
2591 [(set_attr "type" "idiv")
2592 (set_attr "mode" "SI")])
2593
2594 (define_expand "moddi3"
2595 [(set (match_operand:DI 0 "register_operand" "=h")
2596 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2597 (match_operand:DI 2 "se_register_operand" "d")))
2598 (clobber (match_scratch:DI 3 "=l"))
2599 (clobber (match_scratch:DI 4 "=a"))]
2600 "TARGET_64BIT && !optimize"
2601 "
2602 {
2603 emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2604 if (!TARGET_NO_CHECK_ZERO_DIV)
2605 {
2606 emit_insn (gen_div_trap (operands[2],
2607 GEN_INT (0),
2608 GEN_INT (0x7)));
2609 }
2610 if (TARGET_CHECK_RANGE_DIV)
2611 {
2612 emit_insn (gen_div_trap (operands[2],
2613 copy_to_mode_reg (DImode, GEN_INT (-1)),
2614 GEN_INT (0x6)));
2615 emit_insn (gen_div_trap (operands[2],
2616 copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2617 GEN_INT (0x6)));
2618 }
2619
2620 DONE;
2621 }")
2622
2623 (define_insn "moddi3_internal"
2624 [(set (match_operand:DI 0 "register_operand" "=h")
2625 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2626 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2627 (clobber (match_scratch:SI 3 "=l"))
2628 (clobber (match_scratch:SI 4 "=a"))]
2629 "TARGET_64BIT && !optimize"
2630 "ddiv\\t$0,%1,%2"
2631 [(set_attr "type" "idiv")
2632 (set_attr "mode" "DI")])
2633
2634 (define_expand "udivsi3"
2635 [(set (match_operand:SI 0 "register_operand" "=l")
2636 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2637 (match_operand:SI 2 "register_operand" "d")))
2638 (clobber (match_scratch:SI 3 "=h"))
2639 (clobber (match_scratch:SI 4 "=a"))]
2640 "!optimize"
2641 "
2642 {
2643 emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2644 if (!TARGET_NO_CHECK_ZERO_DIV)
2645 {
2646 emit_insn (gen_div_trap (operands[2],
2647 GEN_INT (0),
2648 GEN_INT (0x7)));
2649 }
2650
2651 DONE;
2652 }")
2653
2654 (define_insn "udivsi3_internal"
2655 [(set (match_operand:SI 0 "register_operand" "=l")
2656 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2657 (match_operand:SI 2 "nonmemory_operand" "di")))
2658 (clobber (match_scratch:SI 3 "=h"))
2659 (clobber (match_scratch:SI 4 "=a"))]
2660 "!optimize"
2661 "divu\\t$0,%1,%2"
2662 [(set_attr "type" "idiv")
2663 (set_attr "mode" "SI")])
2664
2665 (define_expand "udivdi3"
2666 [(set (match_operand:DI 0 "register_operand" "=l")
2667 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2668 (match_operand:DI 2 "se_register_operand" "di")))
2669 (clobber (match_scratch:DI 3 "=h"))
2670 (clobber (match_scratch:DI 4 "=a"))]
2671 "TARGET_64BIT && !optimize"
2672 "
2673 {
2674 emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2675 if (!TARGET_NO_CHECK_ZERO_DIV)
2676 {
2677 emit_insn (gen_div_trap (operands[2],
2678 GEN_INT (0),
2679 GEN_INT (0x7)));
2680 }
2681
2682 DONE;
2683 }")
2684
2685 (define_insn "udivdi3_internal"
2686 [(set (match_operand:DI 0 "register_operand" "=l")
2687 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2688 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2689 (clobber (match_scratch:SI 3 "=h"))
2690 (clobber (match_scratch:SI 4 "=a"))]
2691 "TARGET_64BIT && !optimize"
2692 "ddivu\\t$0,%1,%2"
2693 [(set_attr "type" "idiv")
2694 (set_attr "mode" "DI")])
2695
2696 (define_expand "umodsi3"
2697 [(set (match_operand:SI 0 "register_operand" "=h")
2698 (umod:SI (match_operand:SI 1 "register_operand" "d")
2699 (match_operand:SI 2 "register_operand" "d")))
2700 (clobber (match_scratch:SI 3 "=l"))
2701 (clobber (match_scratch:SI 4 "=a"))]
2702 "!optimize"
2703 "
2704 {
2705 emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2706 if (!TARGET_NO_CHECK_ZERO_DIV)
2707 {
2708 emit_insn (gen_div_trap (operands[2],
2709 GEN_INT (0),
2710 GEN_INT (0x7)));
2711 }
2712
2713 DONE;
2714 }")
2715
2716 (define_insn "umodsi3_internal"
2717 [(set (match_operand:SI 0 "register_operand" "=h")
2718 (umod:SI (match_operand:SI 1 "register_operand" "d")
2719 (match_operand:SI 2 "nonmemory_operand" "di")))
2720 (clobber (match_scratch:SI 3 "=l"))
2721 (clobber (match_scratch:SI 4 "=a"))]
2722 "!optimize"
2723 "divu\\t$0,%1,%2"
2724 [(set_attr "type" "idiv")
2725 (set_attr "mode" "SI")])
2726
2727 (define_expand "umoddi3"
2728 [(set (match_operand:DI 0 "register_operand" "=h")
2729 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2730 (match_operand:DI 2 "se_register_operand" "di")))
2731 (clobber (match_scratch:DI 3 "=l"))
2732 (clobber (match_scratch:DI 4 "=a"))]
2733 "TARGET_64BIT && !optimize"
2734 "
2735 {
2736 emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2737 if (!TARGET_NO_CHECK_ZERO_DIV)
2738 {
2739 emit_insn (gen_div_trap (operands[2],
2740 GEN_INT (0),
2741 GEN_INT (0x7)));
2742 }
2743
2744 DONE;
2745 }")
2746
2747 (define_insn "umoddi3_internal"
2748 [(set (match_operand:DI 0 "register_operand" "=h")
2749 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2750 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2751 (clobber (match_scratch:SI 3 "=l"))
2752 (clobber (match_scratch:SI 4 "=a"))]
2753 "TARGET_64BIT && !optimize"
2754 "ddivu\\t$0,%1,%2"
2755 [(set_attr "type" "idiv")
2756 (set_attr "mode" "DI")])
2757 \f
2758 ;;
2759 ;; ....................
2760 ;;
2761 ;; SQUARE ROOT
2762 ;;
2763 ;; ....................
2764
2765 (define_insn "sqrtdf2"
2766 [(set (match_operand:DF 0 "register_operand" "=f")
2767 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2768 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2769 "sqrt.d\\t%0,%1"
2770 [(set_attr "type" "fsqrt")
2771 (set_attr "mode" "DF")])
2772
2773 (define_insn "sqrtsf2"
2774 [(set (match_operand:SF 0 "register_operand" "=f")
2775 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2776 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2777 "sqrt.s\\t%0,%1"
2778 [(set_attr "type" "fsqrt")
2779 (set_attr "mode" "SF")])
2780
2781 (define_insn ""
2782 [(set (match_operand:DF 0 "register_operand" "=f")
2783 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2784 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2785 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2786 "rsqrt.d\\t%0,%2"
2787 [(set_attr "type" "fsqrt")
2788 (set_attr "mode" "DF")])
2789
2790 (define_insn ""
2791 [(set (match_operand:SF 0 "register_operand" "=f")
2792 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2793 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2794 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2795 "rsqrt.s\\t%0,%2"
2796 [(set_attr "type" "fsqrt")
2797 (set_attr "mode" "SF")])
2798
2799 \f
2800 ;;
2801 ;; ....................
2802 ;;
2803 ;; ABSOLUTE VALUE
2804 ;;
2805 ;; ....................
2806
2807 ;; Do not use the integer abs macro instruction, since that signals an
2808 ;; exception on -2147483648 (sigh).
2809
2810 (define_insn "abssi2"
2811 [(set (match_operand:SI 0 "register_operand" "=d")
2812 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2813 "!TARGET_MIPS16"
2814 "*
2815 {
2816 dslots_jump_total++;
2817 dslots_jump_filled++;
2818 operands[2] = const0_rtx;
2819
2820 if (REGNO (operands[0]) == REGNO (operands[1]))
2821 {
2822 if (GENERATE_BRANCHLIKELY)
2823 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2824 else
2825 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
2826 }
2827 else
2828 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2829 }"
2830 [(set_attr "type" "multi")
2831 (set_attr "mode" "SI")
2832 (set_attr "length" "12")])
2833
2834 (define_insn "absdi2"
2835 [(set (match_operand:DI 0 "register_operand" "=d")
2836 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
2837 "TARGET_64BIT && !TARGET_MIPS16"
2838 "*
2839 {
2840 dslots_jump_total++;
2841 dslots_jump_filled++;
2842 operands[2] = const0_rtx;
2843
2844 if (REGNO (operands[0]) == REGNO (operands[1]))
2845 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
2846 else
2847 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
2848 }"
2849 [(set_attr "type" "multi")
2850 (set_attr "mode" "DI")
2851 (set_attr "length" "12")])
2852
2853 (define_insn "absdf2"
2854 [(set (match_operand:DF 0 "register_operand" "=f")
2855 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2856 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2857 "abs.d\\t%0,%1"
2858 [(set_attr "type" "fabs")
2859 (set_attr "mode" "DF")])
2860
2861 (define_insn "abssf2"
2862 [(set (match_operand:SF 0 "register_operand" "=f")
2863 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2864 "TARGET_HARD_FLOAT"
2865 "abs.s\\t%0,%1"
2866 [(set_attr "type" "fabs")
2867 (set_attr "mode" "SF")])
2868
2869 \f
2870 ;;
2871 ;; ....................
2872 ;;
2873 ;; FIND FIRST BIT INSTRUCTION
2874 ;;
2875 ;; ....................
2876 ;;
2877
2878 (define_insn "ffssi2"
2879 [(set (match_operand:SI 0 "register_operand" "=&d")
2880 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2881 (clobber (match_scratch:SI 2 "=&d"))
2882 (clobber (match_scratch:SI 3 "=&d"))]
2883 "!TARGET_MIPS16"
2884 "*
2885 {
2886 dslots_jump_total += 2;
2887 dslots_jump_filled += 2;
2888 operands[4] = const0_rtx;
2889
2890 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2891 return \"%(\\
2892 move\\t%0,%z4\\n\\
2893 \\tbeq\\t%1,%z4,2f\\n\\
2894 %~1:\\tand\\t%2,%1,0x0001\\n\\
2895 \\taddu\\t%0,%0,1\\n\\
2896 \\tbeq\\t%2,%z4,1b\\n\\
2897 \\tsrl\\t%1,%1,1\\n\\
2898 %~2:%)\";
2899
2900 return \"%(\\
2901 move\\t%0,%z4\\n\\
2902 \\tmove\\t%3,%1\\n\\
2903 \\tbeq\\t%3,%z4,2f\\n\\
2904 %~1:\\tand\\t%2,%3,0x0001\\n\\
2905 \\taddu\\t%0,%0,1\\n\\
2906 \\tbeq\\t%2,%z4,1b\\n\\
2907 \\tsrl\\t%3,%3,1\\n\\
2908 %~2:%)\";
2909 }"
2910 [(set_attr "type" "multi")
2911 (set_attr "mode" "SI")
2912 (set_attr "length" "12")])
2913
2914 (define_insn "ffsdi2"
2915 [(set (match_operand:DI 0 "register_operand" "=&d")
2916 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
2917 (clobber (match_scratch:DI 2 "=&d"))
2918 (clobber (match_scratch:DI 3 "=&d"))]
2919 "TARGET_64BIT && !TARGET_MIPS16"
2920 "*
2921 {
2922 dslots_jump_total += 2;
2923 dslots_jump_filled += 2;
2924 operands[4] = const0_rtx;
2925
2926 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2927 return \"%(\\
2928 move\\t%0,%z4\\n\\
2929 \\tbeq\\t%1,%z4,2f\\n\\
2930 %~1:\\tand\\t%2,%1,0x0001\\n\\
2931 \\tdaddu\\t%0,%0,1\\n\\
2932 \\tbeq\\t%2,%z4,1b\\n\\
2933 \\tdsrl\\t%1,%1,1\\n\\
2934 %~2:%)\";
2935
2936 return \"%(\\
2937 move\\t%0,%z4\\n\\
2938 \\tmove\\t%3,%1\\n\\
2939 \\tbeq\\t%3,%z4,2f\\n\\
2940 %~1:\\tand\\t%2,%3,0x0001\\n\\
2941 \\tdaddu\\t%0,%0,1\\n\\
2942 \\tbeq\\t%2,%z4,1b\\n\\
2943 \\tdsrl\\t%3,%3,1\\n\\
2944 %~2:%)\";
2945 }"
2946 [(set_attr "type" "multi")
2947 (set_attr "mode" "DI")
2948 (set_attr "length" "24")])
2949
2950 \f
2951 ;;
2952 ;; ....................
2953 ;;
2954 ;; NEGATION and ONE'S COMPLEMENT
2955 ;;
2956 ;; ....................
2957
2958 (define_insn "negsi2"
2959 [(set (match_operand:SI 0 "register_operand" "=d")
2960 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2961 ""
2962 "*
2963 {
2964 if (TARGET_MIPS16)
2965 return \"neg\\t%0,%1\";
2966 operands[2] = const0_rtx;
2967 return \"subu\\t%0,%z2,%1\";
2968 }"
2969 [(set_attr "type" "arith")
2970 (set_attr "mode" "SI")])
2971
2972 (define_expand "negdi2"
2973 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2974 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
2975 (clobber (match_dup 2))])]
2976 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2977 "
2978 {
2979 if (TARGET_64BIT)
2980 {
2981 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2982 DONE;
2983 }
2984
2985 operands[2] = gen_reg_rtx (SImode);
2986 }")
2987
2988 (define_insn "negdi2_internal"
2989 [(set (match_operand:DI 0 "register_operand" "=d")
2990 (neg:DI (match_operand:DI 1 "register_operand" "d")))
2991 (clobber (match_operand:SI 2 "register_operand" "=d"))]
2992 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2993 "*
2994 {
2995 operands[3] = const0_rtx;
2996 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
2997 }"
2998 [(set_attr "type" "darith")
2999 (set_attr "mode" "DI")
3000 (set_attr "length" "16")])
3001
3002 (define_insn "negdi2_internal_2"
3003 [(set (match_operand:DI 0 "register_operand" "=d")
3004 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3005 "TARGET_64BIT && !TARGET_MIPS16"
3006 "*
3007 {
3008 operands[2] = const0_rtx;
3009 return \"dsubu\\t%0,%z2,%1\";
3010 }"
3011 [(set_attr "type" "arith")
3012 (set_attr "mode" "DI")])
3013
3014 (define_insn "negdf2"
3015 [(set (match_operand:DF 0 "register_operand" "=f")
3016 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3017 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3018 "neg.d\\t%0,%1"
3019 [(set_attr "type" "fneg")
3020 (set_attr "mode" "DF")])
3021
3022 (define_insn "negsf2"
3023 [(set (match_operand:SF 0 "register_operand" "=f")
3024 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3025 "TARGET_HARD_FLOAT"
3026 "neg.s\\t%0,%1"
3027 [(set_attr "type" "fneg")
3028 (set_attr "mode" "SF")])
3029
3030 (define_insn "one_cmplsi2"
3031 [(set (match_operand:SI 0 "register_operand" "=d")
3032 (not:SI (match_operand:SI 1 "register_operand" "d")))]
3033 ""
3034 "*
3035 {
3036 if (TARGET_MIPS16)
3037 return \"not\\t%0,%1\";
3038 operands[2] = const0_rtx;
3039 return \"nor\\t%0,%z2,%1\";
3040 }"
3041 [(set_attr "type" "arith")
3042 (set_attr "mode" "SI")])
3043
3044 (define_insn "one_cmpldi2"
3045 [(set (match_operand:DI 0 "register_operand" "=d")
3046 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3047 ""
3048 "*
3049 {
3050 if (TARGET_MIPS16)
3051 {
3052 if (TARGET_64BIT)
3053 return \"not\\t%0,%1\";
3054 return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3055 }
3056 operands[2] = const0_rtx;
3057 if (TARGET_64BIT)
3058 return \"nor\\t%0,%z2,%1\";
3059 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3060 }"
3061 [(set_attr "type" "darith")
3062 (set_attr "mode" "DI")
3063 (set (attr "length")
3064 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3065 (const_int 4)
3066 (const_int 8)))])
3067
3068 (define_split
3069 [(set (match_operand:DI 0 "register_operand" "")
3070 (not:DI (match_operand:DI 1 "register_operand" "")))]
3071 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3072 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3073 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3074
3075 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3076 (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
3077 "")
3078
3079 \f
3080 ;;
3081 ;; ....................
3082 ;;
3083 ;; LOGICAL
3084 ;;
3085 ;; ....................
3086 ;;
3087
3088 ;; Many of these instructions uses trivial define_expands, because we
3089 ;; want to use a different set of constraints when TARGET_MIPS16.
3090
3091 (define_expand "andsi3"
3092 [(set (match_operand:SI 0 "register_operand" "=d,d")
3093 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3094 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3095 ""
3096 "
3097 {
3098 if (TARGET_MIPS16)
3099 operands[2] = force_reg (SImode, operands[2]);
3100 }")
3101
3102 (define_insn ""
3103 [(set (match_operand:SI 0 "register_operand" "=d,d")
3104 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3105 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3106 "!TARGET_MIPS16"
3107 "@
3108 and\\t%0,%1,%2
3109 andi\\t%0,%1,%x2"
3110 [(set_attr "type" "arith")
3111 (set_attr "mode" "SI")])
3112
3113 (define_insn ""
3114 [(set (match_operand:SI 0 "register_operand" "=d")
3115 (and:SI (match_operand:SI 1 "register_operand" "%0")
3116 (match_operand:SI 2 "register_operand" "d")))]
3117 "TARGET_MIPS16"
3118 "and\\t%0,%2"
3119 [(set_attr "type" "arith")
3120 (set_attr "mode" "SI")])
3121
3122 (define_expand "anddi3"
3123 [(set (match_operand:DI 0 "register_operand" "=d")
3124 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3125 (match_operand:DI 2 "se_register_operand" "d")))]
3126 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3127 "
3128 {
3129 if (TARGET_MIPS16)
3130 operands[2] = force_reg (DImode, operands[2]);
3131 }")
3132
3133 (define_insn ""
3134 [(set (match_operand:DI 0 "register_operand" "=d")
3135 (and:DI (match_operand:DI 1 "se_register_operand" "d")
3136 (match_operand:DI 2 "se_register_operand" "d")))]
3137 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3138 "*
3139 {
3140 if (TARGET_64BIT)
3141 return \"and\\t%0,%1,%2\";
3142 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3143 }"
3144 [(set_attr "type" "darith")
3145 (set_attr "mode" "DI")
3146 (set (attr "length")
3147 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3148 (const_int 4)
3149 (const_int 8)))])
3150
3151 (define_insn ""
3152 [(set (match_operand:DI 0 "register_operand" "=d")
3153 (and:DI (match_operand:DI 1 "se_register_operand" "0")
3154 (match_operand:DI 2 "se_register_operand" "d")))]
3155 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3156 "*
3157 {
3158 if (TARGET_64BIT)
3159 return \"and\\t%0,%2\";
3160 return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3161 }"
3162 [(set_attr "type" "darith")
3163 (set_attr "mode" "DI")
3164 (set (attr "length")
3165 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3166 (const_int 4)
3167 (const_int 8)))])
3168
3169 (define_split
3170 [(set (match_operand:DI 0 "register_operand" "")
3171 (and:DI (match_operand:DI 1 "register_operand" "")
3172 (match_operand:DI 2 "register_operand" "")))]
3173 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3174 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3175 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3176 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3177
3178 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3179 (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3180 "")
3181
3182 (define_insn "anddi3_internal1"
3183 [(set (match_operand:DI 0 "register_operand" "=d,d")
3184 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3185 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3186 "TARGET_64BIT && !TARGET_MIPS16"
3187 "@
3188 and\\t%0,%1,%2
3189 andi\\t%0,%1,%x2"
3190 [(set_attr "type" "arith")
3191 (set_attr "mode" "DI")])
3192
3193 (define_expand "iorsi3"
3194 [(set (match_operand:SI 0 "register_operand" "=d,d")
3195 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3196 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3197 ""
3198 "
3199 {
3200 if (TARGET_MIPS16)
3201 operands[2] = force_reg (SImode, operands[2]);
3202 }")
3203
3204 (define_insn ""
3205 [(set (match_operand:SI 0 "register_operand" "=d,d")
3206 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3207 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3208 "!TARGET_MIPS16"
3209 "@
3210 or\\t%0,%1,%2
3211 ori\\t%0,%1,%x2"
3212 [(set_attr "type" "arith")
3213 (set_attr "mode" "SI")])
3214
3215 (define_insn ""
3216 [(set (match_operand:SI 0 "register_operand" "=d")
3217 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3218 (match_operand:SI 2 "register_operand" "d")))]
3219 "TARGET_MIPS16"
3220 "or\\t%0,%2"
3221 [(set_attr "type" "arith")
3222 (set_attr "mode" "SI")])
3223
3224 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3225 ;;; TARGET_64BIT
3226
3227 (define_expand "iordi3"
3228 [(set (match_operand:DI 0 "register_operand" "=d")
3229 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3230 (match_operand:DI 2 "se_register_operand" "d")))]
3231 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3232 "")
3233
3234 (define_insn ""
3235 [(set (match_operand:DI 0 "register_operand" "=d")
3236 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3237 (match_operand:DI 2 "se_register_operand" "d")))]
3238 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3239 "*
3240 {
3241 if (TARGET_64BIT)
3242 return \"or\\t%0,%1,%2\";
3243 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3244 }"
3245 [(set_attr "type" "darith")
3246 (set_attr "mode" "DI")
3247 (set (attr "length")
3248 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3249 (const_int 4)
3250 (const_int 8)))])
3251
3252 (define_insn ""
3253 [(set (match_operand:DI 0 "register_operand" "=d")
3254 (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3255 (match_operand:DI 2 "se_register_operand" "d")))]
3256 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3257 "*
3258 {
3259 if (TARGET_64BIT)
3260 return \"or\\t%0,%2\";
3261 return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3262 }"
3263 [(set_attr "type" "darith")
3264 (set_attr "mode" "DI")
3265 (set (attr "length")
3266 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3267 (const_int 4)
3268 (const_int 8)))])
3269
3270 (define_split
3271 [(set (match_operand:DI 0 "register_operand" "")
3272 (ior:DI (match_operand:DI 1 "register_operand" "")
3273 (match_operand:DI 2 "register_operand" "")))]
3274 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3275 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3276 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3277 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3278
3279 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3280 (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3281 "")
3282
3283 (define_expand "xorsi3"
3284 [(set (match_operand:SI 0 "register_operand" "=d,d")
3285 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3286 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3287 ""
3288 "")
3289
3290 (define_insn ""
3291 [(set (match_operand:SI 0 "register_operand" "=d,d")
3292 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3293 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3294 "!TARGET_MIPS16"
3295 "@
3296 xor\\t%0,%1,%2
3297 xori\\t%0,%1,%x2"
3298 [(set_attr "type" "arith")
3299 (set_attr "mode" "SI")])
3300
3301 (define_insn ""
3302 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3303 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3304 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3305 "TARGET_MIPS16"
3306 "@
3307 xor\\t%0,%2
3308 cmpi\\t%1,%2
3309 cmp\\t%1,%2"
3310 [(set_attr "type" "arith")
3311 (set_attr "mode" "SI")
3312 (set_attr_alternative "length"
3313 [(const_int 4)
3314 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3315 (const_int 4)
3316 (const_int 8))
3317 (const_int 4)])])
3318
3319 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3320 ;; the following xordi3_internal pattern.
3321 (define_expand "xordi3"
3322 [(set (match_operand:DI 0 "register_operand" "=d")
3323 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3324 (match_operand:DI 2 "se_register_operand" "d")))]
3325 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3326 "")
3327
3328 (define_insn ""
3329 [(set (match_operand:DI 0 "register_operand" "=d")
3330 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3331 (match_operand:DI 2 "se_register_operand" "d")))]
3332 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3333 "*
3334 {
3335 if (TARGET_64BIT)
3336 return \"xor\\t%0,%1,%2\";
3337 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3338 }"
3339 [(set_attr "type" "darith")
3340 (set_attr "mode" "DI")
3341 (set (attr "length")
3342 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3343 (const_int 4)
3344 (const_int 8)))])
3345
3346 (define_insn ""
3347 [(set (match_operand:DI 0 "register_operand" "=d")
3348 (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3349 (match_operand:DI 2 "se_register_operand" "d")))]
3350 "!TARGET_64BIT && TARGET_MIPS16"
3351 "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3352 [(set_attr "type" "darith")
3353 (set_attr "mode" "DI")
3354 (set_attr "length" "8")])
3355
3356 (define_insn ""
3357 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3358 (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3359 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3360 "TARGET_64BIT && TARGET_MIPS16"
3361 "@
3362 xor\\t%0,%2
3363 cmpi\\t%1,%2
3364 cmp\\t%1,%2"
3365 [(set_attr "type" "arith")
3366 (set_attr "mode" "DI")
3367 (set_attr_alternative "length"
3368 [(const_int 4)
3369 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3370 (const_int 4)
3371 (const_int 8))
3372 (const_int 4)])])
3373
3374 (define_split
3375 [(set (match_operand:DI 0 "register_operand" "")
3376 (xor:DI (match_operand:DI 1 "register_operand" "")
3377 (match_operand:DI 2 "register_operand" "")))]
3378 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3379 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3380 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3381 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3382
3383 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3384 (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3385 "")
3386
3387 (define_insn "xordi3_immed"
3388 [(set (match_operand:DI 0 "register_operand" "=d")
3389 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3390 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3391 "TARGET_64BIT && !TARGET_MIPS16"
3392 "xori\\t%0,%1,%x2"
3393 [(set_attr "type" "arith")
3394 (set_attr "mode" "DI")])
3395
3396 (define_insn "*norsi3"
3397 [(set (match_operand:SI 0 "register_operand" "=d")
3398 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3399 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3400 "!TARGET_MIPS16"
3401 "nor\\t%0,%z1,%z2"
3402 [(set_attr "type" "arith")
3403 (set_attr "mode" "SI")])
3404
3405 (define_insn "*nordi3"
3406 [(set (match_operand:DI 0 "register_operand" "=d")
3407 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3408 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3409 "!TARGET_MIPS16"
3410 "*
3411 {
3412 if (TARGET_64BIT)
3413 return \"nor\\t%0,%z1,%z2\";
3414 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3415 }"
3416 [(set_attr "type" "darith")
3417 (set_attr "mode" "DI")
3418 (set (attr "length")
3419 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3420 (const_int 4)
3421 (const_int 8)))])
3422
3423 (define_split
3424 [(set (match_operand:DI 0 "register_operand" "")
3425 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3426 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3427 "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3428 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3429 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3430 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3431
3432 [(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))))
3433 (set (subreg:SI (match_dup 0) 1) (and:SI (not:SI (subreg:SI (match_dup 1) 1)) (not:SI (subreg:SI (match_dup 2) 1))))]
3434 "")
3435 \f
3436 ;;
3437 ;; ....................
3438 ;;
3439 ;; TRUNCATION
3440 ;;
3441 ;; ....................
3442
3443 (define_insn "truncdfsf2"
3444 [(set (match_operand:SF 0 "register_operand" "=f")
3445 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3446 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3447 "cvt.s.d\\t%0,%1"
3448 [(set_attr "type" "fcvt")
3449 (set_attr "mode" "SF")])
3450
3451 (define_insn "truncdisi2"
3452 [(set (match_operand:SI 0 "register_operand" "=d")
3453 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3454 "TARGET_64BIT"
3455 "*
3456 {
3457 if (TARGET_MIPS16)
3458 return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3459 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3460 }"
3461 [(set_attr "type" "darith")
3462 (set_attr "mode" "SI")
3463 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3464 (const_int 8)
3465 (const_int 16)))])
3466
3467 (define_insn "truncdihi2"
3468 [(set (match_operand:HI 0 "register_operand" "=d")
3469 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3470 "TARGET_64BIT"
3471 "*
3472 {
3473 if (TARGET_MIPS16)
3474 return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3475 return \"andi\\t%0,%1,0xffff\";
3476 }"
3477 [(set_attr "type" "darith")
3478 (set_attr "mode" "HI")
3479 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3480 (const_int 4)
3481 (const_int 16)))])
3482 (define_insn "truncdiqi2"
3483 [(set (match_operand:QI 0 "register_operand" "=d")
3484 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3485 "TARGET_64BIT"
3486 "*
3487 {
3488 if (TARGET_MIPS16)
3489 return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3490 return \"andi\\t%0,%1,0x00ff\";
3491 }"
3492 [(set_attr "type" "darith")
3493 (set_attr "mode" "QI")
3494 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3495 (const_int 4)
3496 (const_int 16)))])
3497
3498 ;; Combiner patterns to optimize shift/truncate combinations.
3499 (define_insn ""
3500 [(set (match_operand:SI 0 "register_operand" "=d")
3501 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3502 (match_operand:DI 2 "small_int" "I"))))]
3503 "TARGET_64BIT && !TARGET_MIPS16"
3504 "*
3505 {
3506 int shift_amt = INTVAL (operands[2]) & 0x3f;
3507
3508 if (shift_amt < 32)
3509 {
3510 operands[2] = GEN_INT (32 - shift_amt);
3511 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3512 }
3513 else
3514 {
3515 operands[2] = GEN_INT (shift_amt);
3516 return \"dsra\\t%0,%1,%2\";
3517 }
3518 }"
3519 [(set_attr "type" "darith")
3520 (set_attr "mode" "SI")
3521 (set_attr "length" "8")])
3522
3523 (define_insn ""
3524 [(set (match_operand:SI 0 "register_operand" "=d")
3525 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3526 (match_operand:DI 2 "small_int" "I"))))]
3527 "TARGET_64BIT && !TARGET_MIPS16"
3528 "*
3529 {
3530 int shift_amt = INTVAL (operands[2]) & 0x3f;
3531
3532 if (shift_amt < 32)
3533 {
3534 operands[2] = GEN_INT (32 - shift_amt);
3535 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3536 }
3537 else if (shift_amt == 32)
3538 return \"dsra\\t%0,%1,32\";
3539 else
3540 {
3541 operands[2] = GEN_INT (shift_amt);
3542 return \"dsrl\\t%0,%1,%2\";
3543 }
3544 }"
3545 [(set_attr "type" "darith")
3546 (set_attr "mode" "SI")
3547 (set_attr "length" "8")])
3548
3549 (define_insn ""
3550 [(set (match_operand:SI 0 "register_operand" "=d")
3551 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3552 (match_operand:DI 2 "small_int" "I"))))]
3553 "TARGET_64BIT"
3554 "*
3555 {
3556 int shift_amt = INTVAL (operands[2]) & 0x3f;
3557
3558 if (shift_amt < 32)
3559 {
3560 operands[2] = GEN_INT (32 + shift_amt);
3561 if (TARGET_MIPS16)
3562 return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3563 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3564 }
3565 else
3566 return \"move\\t%0,%.\";
3567 }"
3568 [(set_attr "type" "darith")
3569 (set_attr "mode" "SI")
3570 (set_attr "length" "8")])
3571
3572 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3573
3574 (define_insn ""
3575 [(set (match_operand:SI 0 "register_operand" "=d")
3576 (zero_extend:SI (truncate:HI
3577 (match_operand:DI 1 "se_register_operand" "d"))))]
3578 "TARGET_64BIT && !TARGET_MIPS16"
3579 "andi\\t%0,%1,0xffff"
3580 [(set_attr "type" "darith")
3581 (set_attr "mode" "SI")])
3582
3583 (define_insn ""
3584 [(set (match_operand:SI 0 "register_operand" "=d")
3585 (zero_extend:SI (truncate:QI
3586 (match_operand:DI 1 "se_register_operand" "d"))))]
3587 "TARGET_64BIT && !TARGET_MIPS16"
3588 "andi\\t%0,%1,0xff"
3589 [(set_attr "type" "darith")
3590 (set_attr "mode" "SI")])
3591
3592 (define_insn ""
3593 [(set (match_operand:HI 0 "register_operand" "=d")
3594 (zero_extend:HI (truncate:QI
3595 (match_operand:DI 1 "se_register_operand" "d"))))]
3596 "TARGET_64BIT && !TARGET_MIPS16"
3597 "andi\\t%0,%1,0xff"
3598 [(set_attr "type" "darith")
3599 (set_attr "mode" "HI")])
3600 \f
3601 ;;
3602 ;; ....................
3603 ;;
3604 ;; ZERO EXTENSION
3605 ;;
3606 ;; ....................
3607
3608 ;; Extension insns.
3609 ;; Those for integer source operand are ordered widest source type first.
3610
3611 (define_expand "zero_extendsidi2"
3612 [(set (match_operand:DI 0 "register_operand" "")
3613 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3614 "TARGET_64BIT"
3615 "
3616 {
3617 if (optimize && GET_CODE (operands[1]) == MEM)
3618 operands[1] = force_not_mem (operands[1]);
3619
3620 if (GET_CODE (operands[1]) != MEM)
3621 {
3622 rtx op1 = gen_lowpart (DImode, operands[1]);
3623 rtx temp = gen_reg_rtx (DImode);
3624 rtx shift = GEN_INT (32);
3625
3626 emit_insn (gen_ashldi3 (temp, op1, shift));
3627 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3628 DONE;
3629 }
3630 }")
3631
3632 (define_insn "zero_extendsidi2_internal"
3633 [(set (match_operand:DI 0 "register_operand" "=d,d")
3634 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3635 "TARGET_64BIT"
3636 "* return mips_move_1word (operands, insn, TRUE);"
3637 [(set_attr "type" "load")
3638 (set_attr "mode" "DI")
3639 (set_attr "length" "4,8")])
3640
3641 (define_expand "zero_extendhisi2"
3642 [(set (match_operand:SI 0 "register_operand" "")
3643 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3644 ""
3645 "
3646 {
3647 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3648 {
3649 rtx op = gen_lowpart (SImode, operands[1]);
3650 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3651
3652 emit_insn (gen_andsi3 (operands[0], op, temp));
3653 DONE;
3654 }
3655 }")
3656
3657 (define_insn ""
3658 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3659 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3660 "!TARGET_MIPS16"
3661 "*
3662 {
3663 if (which_alternative == 0)
3664 return \"andi\\t%0,%1,0xffff\";
3665 else
3666 return mips_move_1word (operands, insn, TRUE);
3667 }"
3668 [(set_attr "type" "arith,load,load")
3669 (set_attr "mode" "SI")
3670 (set_attr "length" "4,4,8")])
3671
3672 (define_insn ""
3673 [(set (match_operand:SI 0 "register_operand" "=d,d")
3674 (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3675 "TARGET_MIPS16"
3676 "* return mips_move_1word (operands, insn, TRUE);"
3677 [(set_attr "type" "load,load")
3678 (set_attr "mode" "SI")
3679 (set_attr "length" "4,8")])
3680
3681 (define_expand "zero_extendhidi2"
3682 [(set (match_operand:DI 0 "register_operand" "")
3683 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3684 "TARGET_64BIT"
3685 "
3686 {
3687 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3688 {
3689 rtx op = gen_lowpart (DImode, operands[1]);
3690 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3691
3692 emit_insn (gen_anddi3 (operands[0], op, temp));
3693 DONE;
3694 }
3695 }")
3696
3697 (define_insn ""
3698 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3699 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3700 "TARGET_64BIT && !TARGET_MIPS16"
3701 "*
3702 {
3703 if (which_alternative == 0)
3704 return \"andi\\t%0,%1,0xffff\";
3705 else
3706 return mips_move_1word (operands, insn, TRUE);
3707 }"
3708 [(set_attr "type" "arith,load,load")
3709 (set_attr "mode" "DI")
3710 (set_attr "length" "4,4,8")])
3711
3712 (define_insn ""
3713 [(set (match_operand:DI 0 "register_operand" "=d,d")
3714 (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3715 "TARGET_64BIT && TARGET_MIPS16"
3716 "* return mips_move_1word (operands, insn, TRUE);"
3717 [(set_attr "type" "load,load")
3718 (set_attr "mode" "DI")
3719 (set_attr "length" "4,8")])
3720
3721 (define_expand "zero_extendqihi2"
3722 [(set (match_operand:HI 0 "register_operand" "")
3723 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3724 ""
3725 "
3726 {
3727 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3728 {
3729 rtx op0 = gen_lowpart (SImode, operands[0]);
3730 rtx op1 = gen_lowpart (SImode, operands[1]);
3731 rtx temp = force_reg (SImode, GEN_INT (0xff));
3732
3733 emit_insn (gen_andsi3 (op0, op1, temp));
3734 DONE;
3735 }
3736 }")
3737
3738 (define_insn ""
3739 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3740 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3741 "!TARGET_MIPS16"
3742 "*
3743 {
3744 if (which_alternative == 0)
3745 return \"andi\\t%0,%1,0x00ff\";
3746 else
3747 return mips_move_1word (operands, insn, TRUE);
3748 }"
3749 [(set_attr "type" "arith,load,load")
3750 (set_attr "mode" "HI")
3751 (set_attr "length" "4,4,8")])
3752
3753 (define_insn ""
3754 [(set (match_operand:HI 0 "register_operand" "=d,d")
3755 (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3756 "TARGET_MIPS16"
3757 "* return mips_move_1word (operands, insn, TRUE);"
3758 [(set_attr "type" "load,load")
3759 (set_attr "mode" "HI")
3760 (set_attr "length" "4,8")])
3761
3762 (define_expand "zero_extendqisi2"
3763 [(set (match_operand:SI 0 "register_operand" "")
3764 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3765 ""
3766 "
3767 {
3768 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3769 {
3770 rtx op = gen_lowpart (SImode, operands[1]);
3771 rtx temp = force_reg (SImode, GEN_INT (0xff));
3772
3773 emit_insn (gen_andsi3 (operands[0], op, temp));
3774 DONE;
3775 }
3776 }")
3777
3778 (define_insn ""
3779 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3780 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3781 "!TARGET_MIPS16"
3782 "*
3783 {
3784 if (which_alternative == 0)
3785 return \"andi\\t%0,%1,0x00ff\";
3786 else
3787 return mips_move_1word (operands, insn, TRUE);
3788 }"
3789 [(set_attr "type" "arith,load,load")
3790 (set_attr "mode" "SI")
3791 (set_attr "length" "4,4,8")])
3792
3793 (define_insn ""
3794 [(set (match_operand:SI 0 "register_operand" "=d,d")
3795 (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3796 "TARGET_MIPS16"
3797 "* return mips_move_1word (operands, insn, TRUE);"
3798 [(set_attr "type" "load,load")
3799 (set_attr "mode" "SI")
3800 (set_attr "length" "4,8")])
3801
3802 (define_expand "zero_extendqidi2"
3803 [(set (match_operand:DI 0 "register_operand" "")
3804 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3805 "TARGET_64BIT"
3806 "
3807 {
3808 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3809 {
3810 rtx op = gen_lowpart (DImode, operands[1]);
3811 rtx temp = force_reg (DImode, GEN_INT (0xff));
3812
3813 emit_insn (gen_anddi3 (operands[0], op, temp));
3814 DONE;
3815 }
3816 }")
3817
3818 (define_insn ""
3819 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3820 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3821 "TARGET_64BIT && !TARGET_MIPS16"
3822 "*
3823 {
3824 if (which_alternative == 0)
3825 return \"andi\\t%0,%1,0x00ff\";
3826 else
3827 return mips_move_1word (operands, insn, TRUE);
3828 }"
3829 [(set_attr "type" "arith,load,load")
3830 (set_attr "mode" "DI")
3831 (set_attr "length" "4,4,8")])
3832
3833 ;; These can be created when a paradoxical subreg operand with an implicit
3834 ;; sign_extend operator is reloaded. Because of the subreg, this is really
3835 ;; a zero extend.
3836 ;; ??? It might be possible to eliminate the need for these patterns by adding
3837 ;; more support to reload for implicit sign_extend operators.
3838 (define_insn "*paradoxical_extendhidi2"
3839 [(set (match_operand:DI 0 "register_operand" "=d,d")
3840 (sign_extend:DI
3841 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
3842 "TARGET_64BIT"
3843 "*
3844 {
3845 return mips_move_1word (operands, insn, TRUE);
3846 }"
3847 [(set_attr "type" "load,load")
3848 (set_attr "mode" "DI")
3849 (set_attr "length" "4,8")])
3850
3851 (define_insn ""
3852 [(set (match_operand:DI 0 "register_operand" "=d,d")
3853 (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3854 "TARGET_64BIT && TARGET_MIPS16"
3855 "* return mips_move_1word (operands, insn, TRUE);"
3856 [(set_attr "type" "load,load")
3857 (set_attr "mode" "DI")
3858 (set_attr "length" "4,8")])
3859 \f
3860 ;;
3861 ;; ....................
3862 ;;
3863 ;; SIGN EXTENSION
3864 ;;
3865 ;; ....................
3866
3867 ;; Extension insns.
3868 ;; Those for integer source operand are ordered widest source type first.
3869
3870 ;; In 64 bit mode, 32 bit values in general registers are always
3871 ;; correctly sign extended. That means that if the target is a
3872 ;; general register, we can sign extend from SImode to DImode just by
3873 ;; doing a move.
3874
3875 (define_insn "extendsidi2"
3876 [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
3877 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
3878 "TARGET_64BIT"
3879 "* return mips_move_1word (operands, insn, FALSE);"
3880 [(set_attr "type" "move,move,move,hilo,load,load")
3881 (set_attr "mode" "DI")
3882 (set_attr "length" "4,4,4,4,4,8")])
3883
3884 ;; These patterns originally accepted general_operands, however, slightly
3885 ;; better code is generated by only accepting register_operands, and then
3886 ;; letting combine generate the lh and lb insns.
3887
3888 (define_expand "extendhidi2"
3889 [(set (match_operand:DI 0 "register_operand" "")
3890 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3891 "TARGET_64BIT"
3892 "
3893 {
3894 if (optimize && GET_CODE (operands[1]) == MEM)
3895 operands[1] = force_not_mem (operands[1]);
3896
3897 if (GET_CODE (operands[1]) != MEM)
3898 {
3899 rtx op1 = gen_lowpart (DImode, operands[1]);
3900 rtx temp = gen_reg_rtx (DImode);
3901 rtx shift = GEN_INT (48);
3902
3903 emit_insn (gen_ashldi3 (temp, op1, shift));
3904 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3905 DONE;
3906 }
3907 }")
3908
3909 (define_insn "extendhidi2_internal"
3910 [(set (match_operand:DI 0 "register_operand" "=d,d")
3911 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3912 "TARGET_64BIT"
3913 "* return mips_move_1word (operands, insn, FALSE);"
3914 [(set_attr "type" "load")
3915 (set_attr "mode" "DI")
3916 (set_attr "length" "4,8")])
3917
3918 (define_expand "extendhisi2"
3919 [(set (match_operand:SI 0 "register_operand" "")
3920 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3921 ""
3922 "
3923 {
3924 if (optimize && GET_CODE (operands[1]) == MEM)
3925 operands[1] = force_not_mem (operands[1]);
3926
3927 if (GET_CODE (operands[1]) != MEM)
3928 {
3929 rtx op1 = gen_lowpart (SImode, operands[1]);
3930 rtx temp = gen_reg_rtx (SImode);
3931 rtx shift = GEN_INT (16);
3932
3933 emit_insn (gen_ashlsi3 (temp, op1, shift));
3934 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3935 DONE;
3936 }
3937 }")
3938
3939 (define_insn "extendhisi2_internal"
3940 [(set (match_operand:SI 0 "register_operand" "=d,d")
3941 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3942 ""
3943 "* return mips_move_1word (operands, insn, FALSE);"
3944 [(set_attr "type" "load")
3945 (set_attr "mode" "SI")
3946 (set_attr "length" "4,8")])
3947
3948 (define_expand "extendqihi2"
3949 [(set (match_operand:HI 0 "register_operand" "")
3950 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3951 ""
3952 "
3953 {
3954 if (optimize && GET_CODE (operands[1]) == MEM)
3955 operands[1] = force_not_mem (operands[1]);
3956
3957 if (GET_CODE (operands[1]) != MEM)
3958 {
3959 rtx op0 = gen_lowpart (SImode, operands[0]);
3960 rtx op1 = gen_lowpart (SImode, operands[1]);
3961 rtx temp = gen_reg_rtx (SImode);
3962 rtx shift = GEN_INT (24);
3963
3964 emit_insn (gen_ashlsi3 (temp, op1, shift));
3965 emit_insn (gen_ashrsi3 (op0, temp, shift));
3966 DONE;
3967 }
3968 }")
3969
3970 (define_insn "extendqihi2_internal"
3971 [(set (match_operand:HI 0 "register_operand" "=d,d")
3972 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3973 ""
3974 "* return mips_move_1word (operands, insn, FALSE);"
3975 [(set_attr "type" "load")
3976 (set_attr "mode" "SI")
3977 (set_attr "length" "4,8")])
3978
3979
3980 (define_expand "extendqisi2"
3981 [(set (match_operand:SI 0 "register_operand" "")
3982 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3983 ""
3984 "
3985 {
3986 if (optimize && GET_CODE (operands[1]) == MEM)
3987 operands[1] = force_not_mem (operands[1]);
3988
3989 if (GET_CODE (operands[1]) != MEM)
3990 {
3991 rtx op1 = gen_lowpart (SImode, operands[1]);
3992 rtx temp = gen_reg_rtx (SImode);
3993 rtx shift = GEN_INT (24);
3994
3995 emit_insn (gen_ashlsi3 (temp, op1, shift));
3996 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3997 DONE;
3998 }
3999 }")
4000
4001 (define_insn "extendqisi2_insn"
4002 [(set (match_operand:SI 0 "register_operand" "=d,d")
4003 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4004 ""
4005 "* return mips_move_1word (operands, insn, FALSE);"
4006 [(set_attr "type" "load")
4007 (set_attr "mode" "SI")
4008 (set_attr "length" "4,8")])
4009
4010 (define_expand "extendqidi2"
4011 [(set (match_operand:DI 0 "register_operand" "")
4012 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4013 "TARGET_64BIT"
4014 "
4015 {
4016 if (optimize && GET_CODE (operands[1]) == MEM)
4017 operands[1] = force_not_mem (operands[1]);
4018
4019 if (GET_CODE (operands[1]) != MEM)
4020 {
4021 rtx op1 = gen_lowpart (DImode, operands[1]);
4022 rtx temp = gen_reg_rtx (DImode);
4023 rtx shift = GEN_INT (56);
4024
4025 emit_insn (gen_ashldi3 (temp, op1, shift));
4026 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4027 DONE;
4028 }
4029 }")
4030
4031 (define_insn "extendqidi2_insn"
4032 [(set (match_operand:DI 0 "register_operand" "=d,d")
4033 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4034 "TARGET_64BIT"
4035 "* return mips_move_1word (operands, insn, FALSE);"
4036 [(set_attr "type" "load")
4037 (set_attr "mode" "DI")
4038 (set_attr "length" "4,8")])
4039
4040
4041 (define_insn "extendsfdf2"
4042 [(set (match_operand:DF 0 "register_operand" "=f")
4043 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4044 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4045 "cvt.d.s\\t%0,%1"
4046 [(set_attr "type" "fcvt")
4047 (set_attr "mode" "DF")])
4048
4049 \f
4050
4051 ;;
4052 ;; ....................
4053 ;;
4054 ;; CONVERSIONS
4055 ;;
4056 ;; ....................
4057
4058 ;; The SImode scratch register can not be shared with address regs used for
4059 ;; operand zero, because then the address in the move instruction will be
4060 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
4061
4062 ;; We need the ?X in alternative 1 so that it will be choosen only if the
4063 ;; destination is a floating point register. Otherwise, alternative 1 can
4064 ;; have lower cost than alternative 0 (because there is one less loser), and
4065 ;; can be choosen when it won't work (because integral reloads into FP
4066 ;; registers are not supported).
4067
4068 (define_insn "fix_truncdfsi2"
4069 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
4070 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4071 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4072 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4073 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4074 "*
4075 {
4076 rtx xoperands[10];
4077
4078 if (which_alternative == 1)
4079 return \"trunc.w.d %0,%1,%2\";
4080
4081 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4082
4083 xoperands[0] = operands[0];
4084 xoperands[1] = operands[3];
4085 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4086 return \"\";
4087 }"
4088 [(set_attr "type" "fcvt")
4089 (set_attr "mode" "DF")
4090 (set_attr "length" "44,36,40,44")])
4091
4092
4093 (define_insn "fix_truncsfsi2"
4094 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
4095 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4096 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4097 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4098 "TARGET_HARD_FLOAT"
4099 "*
4100 {
4101 rtx xoperands[10];
4102
4103 if (which_alternative == 1)
4104 return \"trunc.w.s %0,%1,%2\";
4105
4106 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4107
4108 xoperands[0] = operands[0];
4109 xoperands[1] = operands[3];
4110 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4111 return \"\";
4112 }"
4113 [(set_attr "type" "fcvt")
4114 (set_attr "mode" "SF")
4115 (set_attr "length" "44,36,40,44")])
4116
4117
4118 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4119 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4120 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4121
4122 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
4123 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4124
4125 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4126
4127 (define_insn "fix_truncdfdi2"
4128 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
4129 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4130 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4131 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4132 "*
4133 {
4134 rtx xoperands[10];
4135
4136 if (which_alternative == 1)
4137 return \"trunc.l.d %0,%1\";
4138
4139 output_asm_insn (\"trunc.l.d %2,%1\", operands);
4140
4141 xoperands[0] = operands[0];
4142 xoperands[1] = operands[2];
4143 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
4144 return \"\";
4145 }"
4146 [(set_attr "type" "fcvt")
4147 (set_attr "mode" "DF")
4148 (set_attr "length" "8,4,8,12")])
4149
4150
4151 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4152 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
4153 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
4154 (define_insn "fix_truncsfdi2"
4155 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
4156 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4157 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4158 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4159 "*
4160 {
4161 rtx xoperands[10];
4162
4163 if (which_alternative == 1)
4164 return \"trunc.l.s %0,%1\";
4165
4166 output_asm_insn (\"trunc.l.s %2,%1\", operands);
4167
4168 xoperands[0] = operands[0];
4169 xoperands[1] = operands[2];
4170 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
4171 return \"\";
4172 }"
4173 [(set_attr "type" "fcvt")
4174 (set_attr "mode" "SF")
4175 (set_attr "length" "8,4,8,12")])
4176
4177
4178 (define_insn "floatsidf2"
4179 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4180 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4181 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4182 "*
4183 {
4184 dslots_load_total++;
4185 if (GET_CODE (operands[1]) == MEM)
4186 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4187
4188 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4189 }"
4190 [(set_attr "type" "fcvt")
4191 (set_attr "mode" "DF")
4192 (set_attr "length" "12,16,12")])
4193
4194
4195 (define_insn "floatdidf2"
4196 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4197 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4198 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4199 "*
4200 {
4201 dslots_load_total++;
4202 if (GET_CODE (operands[1]) == MEM)
4203 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4204
4205 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4206 }"
4207 [(set_attr "type" "fcvt")
4208 (set_attr "mode" "DF")
4209 (set_attr "length" "12,16,12")])
4210
4211
4212 (define_insn "floatsisf2"
4213 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4214 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4215 "TARGET_HARD_FLOAT"
4216 "*
4217 {
4218 dslots_load_total++;
4219 if (GET_CODE (operands[1]) == MEM)
4220 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4221
4222 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4223 }"
4224 [(set_attr "type" "fcvt")
4225 (set_attr "mode" "SF")
4226 (set_attr "length" "12,16,12")])
4227
4228
4229 (define_insn "floatdisf2"
4230 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4231 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4232 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4233 "*
4234 {
4235 dslots_load_total++;
4236 if (GET_CODE (operands[1]) == MEM)
4237 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4238
4239 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4240 }"
4241 [(set_attr "type" "fcvt")
4242 (set_attr "mode" "SF")
4243 (set_attr "length" "12,16,12")])
4244
4245
4246 (define_expand "fixuns_truncdfsi2"
4247 [(set (match_operand:SI 0 "register_operand" "")
4248 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4249 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4250 "
4251 {
4252 rtx reg1 = gen_reg_rtx (DFmode);
4253 rtx reg2 = gen_reg_rtx (DFmode);
4254 rtx reg3 = gen_reg_rtx (SImode);
4255 rtx label1 = gen_label_rtx ();
4256 rtx label2 = gen_label_rtx ();
4257 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4258
4259 if (reg1) /* turn off complaints about unreached code */
4260 {
4261 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4262 do_pending_stack_adjust ();
4263
4264 emit_insn (gen_cmpdf (operands[1], reg1));
4265 emit_jump_insn (gen_bge (label1));
4266
4267 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4268 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4269 gen_rtx (LABEL_REF, VOIDmode, label2)));
4270 emit_barrier ();
4271
4272 emit_label (label1);
4273 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4274 emit_move_insn (reg3, GEN_INT (0x80000000));
4275
4276 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4277 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4278
4279 emit_label (label2);
4280
4281 /* allow REG_NOTES to be set on last insn (labels don't have enough
4282 fields, and can't be used for REG_NOTES anyway). */
4283 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4284 DONE;
4285 }
4286 }")
4287
4288
4289 (define_expand "fixuns_truncdfdi2"
4290 [(set (match_operand:DI 0 "register_operand" "")
4291 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4292 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4293 "
4294 {
4295 rtx reg1 = gen_reg_rtx (DFmode);
4296 rtx reg2 = gen_reg_rtx (DFmode);
4297 rtx reg3 = gen_reg_rtx (DImode);
4298 rtx label1 = gen_label_rtx ();
4299 rtx label2 = gen_label_rtx ();
4300 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4301
4302 if (reg1) /* turn off complaints about unreached code */
4303 {
4304 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4305 do_pending_stack_adjust ();
4306
4307 emit_insn (gen_cmpdf (operands[1], reg1));
4308 emit_jump_insn (gen_bge (label1));
4309
4310 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4311 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4312 gen_rtx (LABEL_REF, VOIDmode, label2)));
4313 emit_barrier ();
4314
4315 emit_label (label1);
4316 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4317 emit_move_insn (reg3, GEN_INT (0x80000000));
4318 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4319
4320 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4321 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4322
4323 emit_label (label2);
4324
4325 /* allow REG_NOTES to be set on last insn (labels don't have enough
4326 fields, and can't be used for REG_NOTES anyway). */
4327 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4328 DONE;
4329 }
4330 }")
4331
4332
4333 (define_expand "fixuns_truncsfsi2"
4334 [(set (match_operand:SI 0 "register_operand" "")
4335 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4336 "TARGET_HARD_FLOAT"
4337 "
4338 {
4339 rtx reg1 = gen_reg_rtx (SFmode);
4340 rtx reg2 = gen_reg_rtx (SFmode);
4341 rtx reg3 = gen_reg_rtx (SImode);
4342 rtx label1 = gen_label_rtx ();
4343 rtx label2 = gen_label_rtx ();
4344 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4345
4346 if (reg1) /* turn off complaints about unreached code */
4347 {
4348 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4349 do_pending_stack_adjust ();
4350
4351 emit_insn (gen_cmpsf (operands[1], reg1));
4352 emit_jump_insn (gen_bge (label1));
4353
4354 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4355 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4356 gen_rtx (LABEL_REF, VOIDmode, label2)));
4357 emit_barrier ();
4358
4359 emit_label (label1);
4360 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4361 emit_move_insn (reg3, GEN_INT (0x80000000));
4362
4363 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4364 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4365
4366 emit_label (label2);
4367
4368 /* allow REG_NOTES to be set on last insn (labels don't have enough
4369 fields, and can't be used for REG_NOTES anyway). */
4370 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4371 DONE;
4372 }
4373 }")
4374
4375
4376 (define_expand "fixuns_truncsfdi2"
4377 [(set (match_operand:DI 0 "register_operand" "")
4378 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4379 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4380 "
4381 {
4382 rtx reg1 = gen_reg_rtx (SFmode);
4383 rtx reg2 = gen_reg_rtx (SFmode);
4384 rtx reg3 = gen_reg_rtx (DImode);
4385 rtx label1 = gen_label_rtx ();
4386 rtx label2 = gen_label_rtx ();
4387 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4388
4389 if (reg1) /* turn off complaints about unreached code */
4390 {
4391 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4392 do_pending_stack_adjust ();
4393
4394 emit_insn (gen_cmpsf (operands[1], reg1));
4395 emit_jump_insn (gen_bge (label1));
4396
4397 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4398 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4399 gen_rtx (LABEL_REF, VOIDmode, label2)));
4400 emit_barrier ();
4401
4402 emit_label (label1);
4403 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4404 emit_move_insn (reg3, GEN_INT (0x80000000));
4405 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4406
4407 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4408 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4409
4410 emit_label (label2);
4411
4412 /* allow REG_NOTES to be set on last insn (labels don't have enough
4413 fields, and can't be used for REG_NOTES anyway). */
4414 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4415 DONE;
4416 }
4417 }")
4418
4419 \f
4420 ;;
4421 ;; ....................
4422 ;;
4423 ;; DATA MOVEMENT
4424 ;;
4425 ;; ....................
4426
4427 ;; Bit field extract patterns which use lwl/lwr.
4428
4429 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4430 ;; It isn't clear whether this will give better code.
4431
4432 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4433 (define_expand "extv"
4434 [(set (match_operand 0 "register_operand" "")
4435 (sign_extract (match_operand:QI 1 "memory_operand" "")
4436 (match_operand 2 "immediate_operand" "")
4437 (match_operand 3 "immediate_operand" "")))]
4438 "!TARGET_MIPS16"
4439 "
4440 {
4441 /* If the field does not start on a byte boundary, then fail. */
4442 if (INTVAL (operands[3]) % 8 != 0)
4443 FAIL;
4444
4445 /* MIPS I and MIPS II can only handle a 32bit field. */
4446 if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4447 FAIL;
4448
4449 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4450 if (TARGET_64BIT
4451 && INTVAL (operands[2]) != 64
4452 && INTVAL (operands[2]) != 32)
4453 FAIL;
4454
4455 /* This can happen for a 64 bit target, when extracting a value from
4456 a 64 bit union member. extract_bit_field doesn't verify that our
4457 source matches the predicate, so we force it to be a MEM here. */
4458 if (GET_CODE (operands[1]) != MEM)
4459 FAIL;
4460
4461 /* Change the mode to BLKmode for aliasing purposes. */
4462 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4463
4464 /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
4465 if (INTVAL (operands[2]) == 64)
4466 emit_insn (gen_movdi_uld (operands[0], operands[1]));
4467 else
4468 {
4469 if (TARGET_64BIT)
4470 {
4471 operands[0] = gen_lowpart (SImode, operands[0]);
4472 if (operands[0] == NULL_RTX)
4473 FAIL;
4474 }
4475 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4476 }
4477 DONE;
4478 }")
4479
4480 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4481 (define_expand "extzv"
4482 [(set (match_operand 0 "register_operand" "")
4483 (zero_extract (match_operand:QI 1 "memory_operand" "")
4484 (match_operand 2 "immediate_operand" "")
4485 (match_operand 3 "immediate_operand" "")))]
4486 "!TARGET_MIPS16"
4487 "
4488 {
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)
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;
4508
4509 /* Change the mode to BLKmode for aliasing purposes. */
4510 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4511
4512 /* Otherwise, emit a lwl/lwr 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 }
4525 DONE;
4526 }")
4527
4528 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4529 (define_expand "insv"
4530 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4531 (match_operand 1 "immediate_operand" "")
4532 (match_operand 2 "immediate_operand" ""))
4533 (match_operand 3 "register_operand" ""))]
4534 "!TARGET_MIPS16"
4535 "
4536 {
4537 /* If the field does not start on a byte boundary, then fail. */
4538 if (INTVAL (operands[2]) % 8 != 0)
4539 FAIL;
4540
4541 /* MIPS I and MIPS II can only handle a 32bit field. */
4542 if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4543 FAIL;
4544
4545 /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
4546 if (TARGET_64BIT
4547 && INTVAL (operands[1]) != 64
4548 && INTVAL (operands[1]) != 32)
4549 FAIL;
4550
4551 /* This can happen for a 64 bit target, when storing into a 32 bit union
4552 member. store_bit_field doesn't verify that our target matches the
4553 predicate, so we force it to be a MEM here. */
4554 if (GET_CODE (operands[0]) != MEM)
4555 FAIL;
4556
4557 /* Change the mode to BLKmode for aliasing purposes. */
4558 operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
4559
4560 /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
4561 if (INTVAL (operands[1]) == 64)
4562 emit_insn (gen_movdi_usd (operands[0], operands[3]));
4563 else
4564 {
4565 if (TARGET_64BIT)
4566 {
4567 operands[3] = gen_lowpart (SImode, operands[3]);
4568 if (operands[3] == NULL_RTX)
4569 FAIL;
4570 }
4571 emit_insn (gen_movsi_usw (operands[0], operands[3]));
4572 }
4573 DONE;
4574 }")
4575
4576 ;; unaligned word moves generated by the bit field patterns
4577
4578 (define_insn "movsi_ulw"
4579 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4580 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4581 "!TARGET_MIPS16"
4582 "*
4583 {
4584 rtx offset = const0_rtx;
4585 rtx addr = XEXP (operands[1], 0);
4586 rtx mem_addr = eliminate_constant_term (addr, &offset);
4587 const char *ret;
4588
4589 if (TARGET_STATS)
4590 mips_count_memory_refs (operands[1], 2);
4591
4592 /* The stack/frame pointers are always aligned, so we can convert
4593 to the faster lw if we are referencing an aligned stack location. */
4594
4595 if ((INTVAL (offset) & 3) == 0
4596 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4597 ret = \"lw\\t%0,%1\";
4598 else
4599 ret = \"ulw\\t%0,%1\";
4600
4601 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4602 }"
4603 [(set_attr "type" "load,load")
4604 (set_attr "mode" "SI")
4605 (set_attr "length" "8,16")])
4606
4607 (define_insn "movsi_usw"
4608 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4609 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4610 "!TARGET_MIPS16"
4611 "*
4612 {
4613 rtx offset = const0_rtx;
4614 rtx addr = XEXP (operands[0], 0);
4615 rtx mem_addr = eliminate_constant_term (addr, &offset);
4616
4617 if (TARGET_STATS)
4618 mips_count_memory_refs (operands[0], 2);
4619
4620 /* The stack/frame pointers are always aligned, so we can convert
4621 to the faster sw if we are referencing an aligned stack location. */
4622
4623 if ((INTVAL (offset) & 3) == 0
4624 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4625 return \"sw\\t%1,%0\";
4626
4627 return \"usw\\t%z1,%0\";
4628 }"
4629 [(set_attr "type" "store")
4630 (set_attr "mode" "SI")
4631 (set_attr "length" "8,16")])
4632
4633 ;; Bit field extract patterns which use ldl/ldr.
4634
4635 ;; unaligned double word moves generated by the bit field patterns
4636
4637 (define_insn "movdi_uld"
4638 [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4639 (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4640 ""
4641 "*
4642 {
4643 rtx offset = const0_rtx;
4644 rtx addr = XEXP (operands[1], 0);
4645 rtx mem_addr = eliminate_constant_term (addr, &offset);
4646 const char *ret;
4647
4648 if (TARGET_STATS)
4649 mips_count_memory_refs (operands[1], 2);
4650
4651 /* The stack/frame pointers are always aligned, so we can convert
4652 to the faster lw if we are referencing an aligned stack location. */
4653
4654 if ((INTVAL (offset) & 7) == 0
4655 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4656 ret = \"ld\\t%0,%1\";
4657 else
4658 ret = \"uld\\t%0,%1\";
4659
4660 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4661 }"
4662 [(set_attr "type" "load,load")
4663 (set_attr "mode" "SI")
4664 (set_attr "length" "8,16")])
4665
4666 (define_insn "movdi_usd"
4667 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4668 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4669 ""
4670 "*
4671 {
4672 rtx offset = const0_rtx;
4673 rtx addr = XEXP (operands[0], 0);
4674 rtx mem_addr = eliminate_constant_term (addr, &offset);
4675
4676 if (TARGET_STATS)
4677 mips_count_memory_refs (operands[0], 2);
4678
4679 /* The stack/frame pointers are always aligned, so we can convert
4680 to the faster sw if we are referencing an aligned stack location. */
4681
4682 if ((INTVAL (offset) & 7) == 0
4683 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4684 return \"sd\\t%1,%0\";
4685
4686 return \"usd\\t%z1,%0\";
4687 }"
4688 [(set_attr "type" "store")
4689 (set_attr "mode" "SI")
4690 (set_attr "length" "8,16")])
4691
4692 ;; These two patterns support loading addresses with two instructions instead
4693 ;; of using the macro instruction la.
4694
4695 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4696 ;; unnecessary.
4697
4698 (define_insn "high"
4699 [(set (match_operand:SI 0 "register_operand" "=r")
4700 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4701 "mips_split_addresses && !TARGET_MIPS16"
4702 "lui\\t%0,%%hi(%1) # high"
4703 [(set_attr "type" "move")])
4704
4705 (define_insn "low"
4706 [(set (match_operand:SI 0 "register_operand" "=r")
4707 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4708 (match_operand:SI 2 "immediate_operand" "")))]
4709 "mips_split_addresses && !TARGET_MIPS16"
4710 "addiu\\t%0,%1,%%lo(%2) # low"
4711 [(set_attr "type" "arith")
4712 (set_attr "mode" "SI")])
4713
4714 ;; 64-bit integer moves
4715
4716 ;; Unlike most other insns, the move insns can't be split with
4717 ;; different predicates, because register spilling and other parts of
4718 ;; the compiler, have memoized the insn number already.
4719
4720 (define_expand "movdi"
4721 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4722 (match_operand:DI 1 "general_operand" ""))]
4723 ""
4724 "
4725 {
4726 if (mips_split_addresses && mips_check_split (operands[1], DImode))
4727 {
4728 enum machine_mode mode = GET_MODE (operands[0]);
4729 rtx tem = ((reload_in_progress | reload_completed)
4730 ? operands[0] : gen_reg_rtx (mode));
4731
4732 emit_insn (gen_rtx (SET, VOIDmode, tem,
4733 gen_rtx (HIGH, mode, operands[1])));
4734
4735 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4736 }
4737
4738 /* If we are generating embedded PIC code, and we are referring to a
4739 symbol in the .text section, we must use an offset from the start
4740 of the function. */
4741 if (TARGET_EMBEDDED_PIC
4742 && (GET_CODE (operands[1]) == LABEL_REF
4743 || (GET_CODE (operands[1]) == SYMBOL_REF
4744 && ! SYMBOL_REF_FLAG (operands[1]))))
4745 {
4746 rtx temp;
4747
4748 temp = embedded_pic_offset (operands[1]);
4749 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4750 force_reg (DImode, temp));
4751 emit_move_insn (operands[0], force_reg (DImode, temp));
4752 DONE;
4753 }
4754
4755 /* If operands[1] is a constant address illegal for pic, then we need to
4756 handle it just like LEGITIMIZE_ADDRESS does. */
4757 if (flag_pic && pic_address_needs_scratch (operands[1]))
4758 {
4759 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4760 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4761
4762 if (! SMALL_INT (temp2))
4763 temp2 = force_reg (DImode, temp2);
4764
4765 emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
4766 DONE;
4767 }
4768
4769 /* On the mips16, we can handle a GP relative reference by adding in
4770 $gp. We need to check the name to see whether this is a string
4771 constant. */
4772 if (TARGET_MIPS16
4773 && register_operand (operands[0], DImode)
4774 && GET_CODE (operands[1]) == SYMBOL_REF
4775 && SYMBOL_REF_FLAG (operands[1]))
4776 {
4777 char *name = XSTR (operands[1], 0);
4778
4779 if (name[0] != '*'
4780 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4781 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4782 {
4783 rtx base_reg;
4784
4785 if (reload_in_progress || reload_completed)
4786 {
4787 /* In movsi we use the constant table here. However, in
4788 this case, we're better off copying $28 into a
4789 register and adding, because the constant table entry
4790 would be 8 bytes. */
4791 base_reg = operands[0];
4792 emit_move_insn (base_reg,
4793 gen_rtx (CONST, DImode,
4794 gen_rtx (REG, DImode,
4795 GP_REG_FIRST + 28)));
4796 }
4797 else
4798 {
4799 base_reg = gen_reg_rtx (Pmode);
4800 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4801 }
4802
4803 emit_move_insn (operands[0],
4804 gen_rtx (PLUS, Pmode, base_reg,
4805 mips16_gp_offset (operands[1])));
4806 DONE;
4807 }
4808 }
4809
4810 if ((reload_in_progress | reload_completed) == 0
4811 && !register_operand (operands[0], DImode)
4812 && !register_operand (operands[1], DImode)
4813 && (TARGET_MIPS16
4814 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4815 && operands[1] != CONST0_RTX (DImode))))
4816 {
4817 rtx temp = force_reg (DImode, operands[1]);
4818 emit_move_insn (operands[0], temp);
4819 DONE;
4820 }
4821 }")
4822
4823 ;; For mips16, we need a special case to handle storing $31 into
4824 ;; memory, since we don't have a constraint to match $31. This
4825 ;; instruction can be generated by save_restore_insns.
4826
4827 (define_insn ""
4828 [(set (match_operand:DI 0 "memory_operand" "R,m")
4829 (reg:DI 31))]
4830 "TARGET_MIPS16 && TARGET_64BIT"
4831 "*
4832 {
4833 operands[1] = gen_rtx (REG, DImode, 31);
4834 return mips_move_2words (operands, insn);
4835 }"
4836 [(set_attr "type" "store")
4837 (set_attr "mode" "DI")
4838 (set_attr "length" "4,8")])
4839
4840 (define_insn "movdi_internal"
4841 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
4842 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
4843 "!TARGET_64BIT && !TARGET_MIPS16
4844 && (register_operand (operands[0], DImode)
4845 || register_operand (operands[1], DImode)
4846 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4847 || operands[1] == CONST0_RTX (DImode))"
4848 "* return mips_move_2words (operands, insn); "
4849 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo")
4850 (set_attr "mode" "DI")
4851 (set_attr "length" "8,16,8,16,8,16,8,8,8")])
4852
4853 (define_insn ""
4854 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
4855 (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
4856 "!TARGET_64BIT && TARGET_MIPS16
4857 && (register_operand (operands[0], DImode)
4858 || register_operand (operands[1], DImode))"
4859 "* return mips_move_2words (operands, insn);"
4860 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
4861 (set_attr "mode" "DI")
4862 (set_attr "length" "8,8,8,8,12,8,16,8,16,8")])
4863
4864 (define_split
4865 [(set (match_operand:DI 0 "register_operand" "")
4866 (match_operand:DI 1 "register_operand" ""))]
4867 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4868 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4869 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4870
4871 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4872 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4873 "")
4874
4875 (define_insn "movdi_internal2"
4876 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
4877 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
4878 "TARGET_64BIT && !TARGET_MIPS16
4879 && (register_operand (operands[0], DImode)
4880 || se_register_operand (operands[1], DImode)
4881 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4882 || operands[1] == CONST0_RTX (DImode))"
4883 "* return mips_move_2words (operands, insn); "
4884 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
4885 (set_attr "mode" "DI")
4886 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,8")])
4887
4888 (define_insn ""
4889 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
4890 (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
4891 "TARGET_64BIT && TARGET_MIPS16
4892 && (register_operand (operands[0], DImode)
4893 || se_register_operand (operands[1], DImode))"
4894 "* return mips_move_2words (operands, insn);"
4895 [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
4896 (set_attr "mode" "DI")
4897 (set_attr_alternative "length"
4898 [(const_int 4)
4899 (const_int 4)
4900 (const_int 4)
4901 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4902 (const_int 4)
4903 (const_int 8))
4904 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4905 (const_int 8)
4906 (const_int 12))
4907 (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
4908 (const_int 4)
4909 (const_int 8))
4910 (const_int 4)
4911 (const_int 8)
4912 (const_int 4)
4913 (const_int 8)
4914 (const_int 4)])])
4915
4916 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4917 ;; when the original load is a 4 byte instruction but the add and the
4918 ;; load are 2 2 byte instructions.
4919
4920 (define_split
4921 [(set (match_operand:DI 0 "register_operand" "")
4922 (mem:DI (plus:DI (match_dup 0)
4923 (match_operand:DI 1 "const_int_operand" ""))))]
4924 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4925 && GET_CODE (operands[0]) == REG
4926 && M16_REG_P (REGNO (operands[0]))
4927 && GET_CODE (operands[1]) == CONST_INT
4928 && ((INTVAL (operands[1]) < 0
4929 && INTVAL (operands[1]) >= -0x10)
4930 || (INTVAL (operands[1]) >= 32 * 8
4931 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4932 || (INTVAL (operands[1]) >= 0
4933 && INTVAL (operands[1]) < 32 * 8
4934 && (INTVAL (operands[1]) & 7) != 0))"
4935 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4936 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4937 "
4938 {
4939 HOST_WIDE_INT val = INTVAL (operands[1]);
4940
4941 if (val < 0)
4942 operands[2] = GEN_INT (0);
4943 else if (val >= 32 * 8)
4944 {
4945 int off = val & 7;
4946
4947 operands[1] = GEN_INT (0x8 + off);
4948 operands[2] = GEN_INT (val - off - 0x8);
4949 }
4950 else
4951 {
4952 int off = val & 7;
4953
4954 operands[1] = GEN_INT (off);
4955 operands[2] = GEN_INT (val - off);
4956 }
4957 }")
4958
4959 ;; Handle input reloads in DImode.
4960 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
4961 ;; see it as the source or the destination, depending upon which way
4962 ;; reload handles the instruction.
4963 ;; Making the second operand TImode is a trick. The compiler may
4964 ;; reuse the same register for operand 0 and operand 2. Using TImode
4965 ;; gives us two registers, so we can always use the one which is not
4966 ;; used.
4967
4968 (define_expand "reload_indi"
4969 [(set (match_operand:DI 0 "register_operand" "=b")
4970 (match_operand:DI 1 "" "b"))
4971 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
4972 "TARGET_64BIT"
4973 "
4974 {
4975 rtx scratch = gen_rtx (REG, DImode,
4976 (REGNO (operands[0]) == REGNO (operands[2])
4977 ? REGNO (operands[2]) + 1
4978 : REGNO (operands[2])));
4979
4980 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4981 {
4982 if (GET_CODE (operands[1]) == MEM)
4983 {
4984 rtx memword, offword, hiword, loword;
4985 rtx addr = find_replacement (&XEXP (operands[1], 0));
4986 rtx op1 = change_address (operands[1], VOIDmode, addr);
4987
4988 scratch = gen_rtx (REG, SImode, REGNO (scratch));
4989 memword = change_address (op1, SImode, NULL_RTX);
4990 offword = change_address (adj_offsettable_operand (op1, 4),
4991 SImode, NULL_RTX);
4992 if (BYTES_BIG_ENDIAN)
4993 {
4994 hiword = memword;
4995 loword = offword;
4996 }
4997 else
4998 {
4999 hiword = offword;
5000 loword = memword;
5001 }
5002 emit_move_insn (scratch, hiword);
5003 emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
5004 emit_move_insn (scratch, loword);
5005 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5006 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5007 }
5008 else
5009 {
5010 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5011 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5012 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5013 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5014 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5015 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5016 }
5017 DONE;
5018 }
5019 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5020 {
5021 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5022 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5023 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5024 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5025 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5026 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5027 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5028 DONE;
5029 }
5030 /* This handles moves between a float register and HI/LO. */
5031 emit_move_insn (scratch, operands[1]);
5032 emit_move_insn (operands[0], scratch);
5033 DONE;
5034 }")
5035
5036 ;; Handle output reloads in DImode.
5037
5038 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5039 ;; use a TImode scratch reg.
5040
5041 (define_expand "reload_outdi"
5042 [(set (match_operand:DI 0 "" "=b")
5043 (match_operand:DI 1 "se_register_operand" "b"))
5044 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5045 "TARGET_64BIT"
5046 "
5047 {
5048 rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5049
5050 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5051 {
5052 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5053 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5054 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5055 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5056 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5057 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5058 DONE;
5059 }
5060 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5061 {
5062 if (GET_CODE (operands[0]) == MEM)
5063 {
5064 rtx scratch, memword, offword, hiword, loword;
5065 rtx addr = find_replacement (&XEXP (operands[0], 0));
5066 rtx op0 = change_address (operands[0], VOIDmode, addr);
5067
5068 scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
5069 memword = change_address (op0, SImode, NULL_RTX);
5070 offword = change_address (adj_offsettable_operand (op0, 4),
5071 SImode, NULL_RTX);
5072 if (BYTES_BIG_ENDIAN)
5073 {
5074 hiword = memword;
5075 loword = offword;
5076 }
5077 else
5078 {
5079 hiword = offword;
5080 loword = memword;
5081 }
5082 emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
5083 emit_move_insn (hiword, scratch);
5084 emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
5085 emit_move_insn (loword, scratch);
5086 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5087 }
5088 else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5089 {
5090 /* Handle the case where operand[0] is not a 'd' register,
5091 and hence we can not directly move from the HILO register
5092 into it. */
5093 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5094 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5095 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5096 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5097 emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5098 emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5099 emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5100 emit_insn (gen_movdi (operands[0], scratch));
5101 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5102 }
5103 else
5104 {
5105 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5106 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5107 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5108 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5109 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5110 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5111 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5112 }
5113 DONE;
5114 }
5115 /* This handles moves between a float register and HI/LO. */
5116 emit_move_insn (scratch, operands[1]);
5117 emit_move_insn (operands[0], scratch);
5118 DONE;
5119 }")
5120
5121 ;; 32-bit Integer moves
5122
5123 (define_split
5124 [(set (match_operand:SI 0 "register_operand" "")
5125 (match_operand:SI 1 "large_int" ""))]
5126 "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5127 [(set (match_dup 0)
5128 (match_dup 2))
5129 (set (match_dup 0)
5130 (ior:SI (match_dup 0)
5131 (match_dup 3)))]
5132 "
5133 {
5134 operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
5135 operands[3] = GEN_INT (INTVAL (operands[1]) & 0x0000ffff);
5136 }")
5137
5138 ;; Unlike most other insns, the move insns can't be split with
5139 ;; different predicates, because register spilling and other parts of
5140 ;; the compiler, have memoized the insn number already.
5141
5142 (define_expand "movsi"
5143 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5144 (match_operand:SI 1 "general_operand" ""))]
5145 ""
5146 "
5147 {
5148 if (mips_split_addresses && mips_check_split (operands[1], SImode))
5149 {
5150 enum machine_mode mode = GET_MODE (operands[0]);
5151 rtx tem = ((reload_in_progress | reload_completed)
5152 ? operands[0] : gen_reg_rtx (mode));
5153
5154 emit_insn (gen_rtx (SET, VOIDmode, tem,
5155 gen_rtx (HIGH, mode, operands[1])));
5156
5157 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
5158 }
5159
5160 /* If we are generating embedded PIC code, and we are referring to a
5161 symbol in the .text section, we must use an offset from the start
5162 of the function. */
5163 if (TARGET_EMBEDDED_PIC
5164 && (GET_CODE (operands[1]) == LABEL_REF
5165 || (GET_CODE (operands[1]) == SYMBOL_REF
5166 && ! SYMBOL_REF_FLAG (operands[1]))))
5167 {
5168 rtx temp;
5169
5170 temp = embedded_pic_offset (operands[1]);
5171 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
5172 force_reg (SImode, temp));
5173 emit_move_insn (operands[0], force_reg (SImode, temp));
5174 DONE;
5175 }
5176
5177 /* If operands[1] is a constant address invalid for pic, then we need to
5178 handle it just like LEGITIMIZE_ADDRESS does. */
5179 if (flag_pic && pic_address_needs_scratch (operands[1]))
5180 {
5181 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5182 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5183
5184 if (! SMALL_INT (temp2))
5185 temp2 = force_reg (SImode, temp2);
5186
5187 emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
5188 DONE;
5189 }
5190
5191 /* On the mips16, we can handle a GP relative reference by adding in
5192 $gp. We need to check the name to see whether this is a string
5193 constant. */
5194 if (TARGET_MIPS16
5195 && register_operand (operands[0], SImode)
5196 && GET_CODE (operands[1]) == SYMBOL_REF
5197 && SYMBOL_REF_FLAG (operands[1]))
5198 {
5199 char *name = XSTR (operands[1], 0);
5200
5201 if (name[0] != '*'
5202 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5203 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5204 {
5205 rtx base_reg;
5206
5207 if (reload_in_progress || reload_completed)
5208 {
5209 /* We need to reload this address. In this case we
5210 aren't going to have a chance to combine loading the
5211 address with the load or store. That means that we
5212 can either generate a 2 byte move followed by a 4
5213 byte addition, or a 2 byte load with a 4 byte entry
5214 in the constant table. Since the entry in the
5215 constant table might be shared, we're better off, on
5216 average, loading the address from the constant table. */
5217 emit_move_insn (operands[0],
5218 force_const_mem (SImode, operands[1]));
5219 DONE;
5220 }
5221
5222 base_reg = gen_reg_rtx (Pmode);
5223 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5224
5225 emit_move_insn (operands[0],
5226 gen_rtx (PLUS, Pmode, base_reg,
5227 mips16_gp_offset (operands[1])));
5228 DONE;
5229 }
5230 }
5231
5232 if ((reload_in_progress | reload_completed) == 0
5233 && !register_operand (operands[0], SImode)
5234 && !register_operand (operands[1], SImode)
5235 && (TARGET_MIPS16
5236 || GET_CODE (operands[1]) != CONST_INT
5237 || INTVAL (operands[1]) != 0))
5238 {
5239 rtx temp = force_reg (SImode, operands[1]);
5240 emit_move_insn (operands[0], temp);
5241 DONE;
5242 }
5243 }")
5244
5245 ;; For mips16, we need a special case to handle storing $31 into
5246 ;; memory, since we don't have a constraint to match $31. This
5247 ;; instruction can be generated by save_restore_insns.
5248
5249 (define_insn ""
5250 [(set (match_operand:SI 0 "memory_operand" "R,m")
5251 (reg:SI 31))]
5252 "TARGET_MIPS16"
5253 "*
5254 {
5255 operands[1] = gen_rtx (REG, SImode, 31);
5256 return mips_move_1word (operands, insn, FALSE);
5257 }"
5258 [(set_attr "type" "store")
5259 (set_attr "mode" "SI")
5260 (set_attr "length" "4,8")])
5261
5262 ;; The difference between these two is whether or not ints are allowed
5263 ;; in FP registers (off by default, use -mdebugh to enable).
5264
5265 (define_insn "movsi_internal1"
5266 [(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")
5267 (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"))]
5268 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5269 && (register_operand (operands[0], SImode)
5270 || register_operand (operands[1], SImode)
5271 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5272 "* return mips_move_1word (operands, insn, FALSE);"
5273 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
5274 (set_attr "mode" "SI")
5275 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
5276
5277 (define_insn "movsi_internal2"
5278 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
5279 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
5280 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5281 && (register_operand (operands[0], SImode)
5282 || register_operand (operands[1], SImode)
5283 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5284 "* return mips_move_1word (operands, insn, FALSE);"
5285 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
5286 (set_attr "mode" "SI")
5287 (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,4,4")])
5288
5289 ;; This is the mips16 movsi instruction. We accept a small integer as
5290 ;; the source if the destination is a GP memory reference. This is
5291 ;; because we want the combine pass to turn adding a GP reference to a
5292 ;; register into a direct GP reference, but the combine pass will pass
5293 ;; in the source as a constant if it finds an equivalent one. If the
5294 ;; instruction is recognized, reload will force the constant back out
5295 ;; into a register.
5296
5297 (define_insn ""
5298 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5299 (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5300 "TARGET_MIPS16
5301 && (register_operand (operands[0], SImode)
5302 || register_operand (operands[1], SImode)
5303 || (GET_CODE (operands[0]) == MEM
5304 && GET_CODE (XEXP (operands[0], 0)) == PLUS
5305 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5306 && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5307 && GET_CODE (operands[1]) == CONST_INT
5308 && (SMALL_INT (operands[1])
5309 || SMALL_INT_UNSIGNED (operands[1]))))"
5310 "* return mips_move_1word (operands, insn, FALSE);"
5311 [(set_attr "type" "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5312 (set_attr "mode" "SI")
5313 (set_attr_alternative "length"
5314 [(const_int 4)
5315 (const_int 4)
5316 (const_int 4)
5317 (const_int 8)
5318 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5319 (const_int 4)
5320 (const_int 8))
5321 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5322 (const_int 8)
5323 (const_int 12))
5324 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5325 (const_int 4)
5326 (const_int 8))
5327 (const_int 4)
5328 (const_int 8)
5329 (const_int 4)
5330 (const_int 8)
5331 (const_int 4)
5332 (const_int 4)])])
5333
5334 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5335 ;; when the original load is a 4 byte instruction but the add and the
5336 ;; load are 2 2 byte instructions.
5337
5338 (define_split
5339 [(set (match_operand:SI 0 "register_operand" "")
5340 (mem:SI (plus:SI (match_dup 0)
5341 (match_operand:SI 1 "const_int_operand" ""))))]
5342 "TARGET_MIPS16 && reload_completed
5343 && GET_CODE (operands[0]) == REG
5344 && M16_REG_P (REGNO (operands[0]))
5345 && GET_CODE (operands[1]) == CONST_INT
5346 && ((INTVAL (operands[1]) < 0
5347 && INTVAL (operands[1]) >= -0x80)
5348 || (INTVAL (operands[1]) >= 32 * 4
5349 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5350 || (INTVAL (operands[1]) >= 0
5351 && INTVAL (operands[1]) < 32 * 4
5352 && (INTVAL (operands[1]) & 3) != 0))"
5353 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5354 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5355 "
5356 {
5357 HOST_WIDE_INT val = INTVAL (operands[1]);
5358
5359 if (val < 0)
5360 operands[2] = GEN_INT (0);
5361 else if (val >= 32 * 4)
5362 {
5363 int off = val & 3;
5364
5365 operands[1] = GEN_INT (0x7c + off);
5366 operands[2] = GEN_INT (val - off - 0x7c);
5367 }
5368 else
5369 {
5370 int off = val & 3;
5371
5372 operands[1] = GEN_INT (off);
5373 operands[2] = GEN_INT (val - off);
5374 }
5375 }")
5376
5377 ;; On the mips16, we can split a load of certain constants into a load
5378 ;; and an add. This turns a 4 byte instruction into 2 2 byte
5379 ;; instructions.
5380
5381 (define_split
5382 [(set (match_operand:SI 0 "register_operand" "")
5383 (match_operand:SI 1 "const_int_operand" ""))]
5384 "TARGET_MIPS16 && reload_completed
5385 && GET_CODE (operands[0]) == REG
5386 && M16_REG_P (REGNO (operands[0]))
5387 && GET_CODE (operands[1]) == CONST_INT
5388 && INTVAL (operands[1]) >= 0x100
5389 && INTVAL (operands[1]) <= 0xff + 0x7f"
5390 [(set (match_dup 0) (match_dup 1))
5391 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5392 "
5393 {
5394 int val = INTVAL (operands[1]);
5395
5396 operands[1] = GEN_INT (0xff);
5397 operands[2] = GEN_INT (val - 0xff);
5398 }")
5399
5400 ;; On the mips16, we can split a load of a negative constant into a
5401 ;; load and a neg. That's what mips_move_1word will generate anyhow.
5402
5403 (define_split
5404 [(set (match_operand:SI 0 "register_operand" "")
5405 (match_operand:SI 1 "const_int_operand" ""))]
5406 "TARGET_MIPS16 && reload_completed
5407 && GET_CODE (operands[0]) == REG
5408 && M16_REG_P (REGNO (operands[0]))
5409 && GET_CODE (operands[1]) == CONST_INT
5410 && INTVAL (operands[1]) < 0
5411 && INTVAL (operands[1]) > - 0x8000"
5412 [(set (match_dup 0) (match_dup 1))
5413 (set (match_dup 0) (neg:SI (match_dup 0)))]
5414 "
5415 {
5416 operands[1] = GEN_INT (- INTVAL (operands[1]));
5417 }")
5418
5419 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
5420 ;; order to set the sign bit correctly in the HI register.
5421
5422 (define_expand "reload_outsi"
5423 [(set (match_operand:SI 0 "general_operand" "=b")
5424 (match_operand:SI 1 "register_operand" "b"))
5425 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5426 "TARGET_64BIT || TARGET_MIPS16"
5427 "
5428 {
5429 if (TARGET_64BIT
5430 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5431 {
5432 emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
5433 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5434 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5435 emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5436 DONE;
5437 }
5438 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5439 if (TARGET_MIPS16
5440 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5441 {
5442 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5443 /* This is gen_mulsi3_internal, but we need to fill in the
5444 scratch registers. */
5445 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5446 gen_rtvec (3,
5447 gen_rtx (SET, VOIDmode,
5448 operands[0],
5449 gen_rtx (MULT, SImode,
5450 operands[1],
5451 operands[2])),
5452 gen_rtx (CLOBBER, VOIDmode,
5453 gen_rtx (REG, SImode, 64)),
5454 gen_rtx (CLOBBER, VOIDmode,
5455 gen_rtx (REG, SImode, 66)))));
5456 DONE;
5457 }
5458 /* FIXME: I don't know how to get a value into the HI register. */
5459 if (GET_CODE (operands[0]) == REG
5460 && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5461 : GP_REG_P (REGNO (operands[0]))))
5462 {
5463 emit_move_insn (operands[0], operands[1]);
5464 DONE;
5465 }
5466 /* This handles moves between a float register and HI/LO. */
5467 emit_move_insn (operands[2], operands[1]);
5468 emit_move_insn (operands[0], operands[2]);
5469 DONE;
5470 }")
5471
5472 ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5473 ;; so we use a mult. ??? This is hideous, and we ought to figure out
5474 ;; something better.
5475
5476 ;; We use no predicate for operand1, because it may be a PLUS, and there
5477 ;; is no convenient predicate for that.
5478
5479 (define_expand "reload_insi"
5480 [(set (match_operand:SI 0 "register_operand" "=b")
5481 (match_operand:SI 1 "" "b"))
5482 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5483 "TARGET_MIPS16"
5484 "
5485 {
5486 if (TARGET_MIPS16
5487 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5488 {
5489 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5490 /* This is gen_mulsi3_internal, but we need to fill in the
5491 scratch registers. */
5492 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5493 gen_rtvec (3,
5494 gen_rtx (SET, VOIDmode,
5495 operands[0],
5496 gen_rtx (MULT, SImode,
5497 operands[1],
5498 operands[2])),
5499 gen_rtx (CLOBBER, VOIDmode,
5500 gen_rtx (REG, SImode, 64)),
5501 gen_rtx (CLOBBER, VOIDmode,
5502 gen_rtx (REG, SImode, 66)))));
5503 DONE;
5504 }
5505
5506 /* If this is a plus, then this must be an add of the stack pointer against
5507 either a hard register or a pseudo. */
5508 if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5509 {
5510 rtx plus_op;
5511
5512 if (XEXP (operands[1], 0) == stack_pointer_rtx)
5513 plus_op = XEXP (operands[1], 1);
5514 else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5515 plus_op = XEXP (operands[1], 0);
5516 else
5517 abort ();
5518
5519 /* We should have a register now. */
5520 if (GET_CODE (plus_op) != REG)
5521 abort ();
5522
5523 if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5524 {
5525 /* We have to have at least one temporary register which is not
5526 overlapping plus_op. */
5527 if (! rtx_equal_p (plus_op, operands[0]))
5528 {
5529 emit_move_insn (operands[0], stack_pointer_rtx);
5530 emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5531 }
5532 else if (! rtx_equal_p (plus_op, operands[2]))
5533 {
5534 emit_move_insn (operands[2], stack_pointer_rtx);
5535 emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5536 }
5537 else
5538 abort ();
5539 }
5540 else
5541 {
5542 /* We need two registers in this case. */
5543 if (! rtx_equal_p (operands[0], operands[2]))
5544 {
5545 emit_move_insn (operands[0], stack_pointer_rtx);
5546 emit_move_insn (operands[2], plus_op);
5547 emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5548 }
5549 else
5550 abort ();
5551 }
5552 DONE;
5553 }
5554
5555 /* FIXME: I don't know how to get a value into the HI register. */
5556 emit_move_insn (operands[0], operands[1]);
5557 DONE;
5558 }")
5559
5560 ;; This insn handles moving CCmode values. It's really just a
5561 ;; slightly simplified copy of movsi_internal2, with additional cases
5562 ;; to move a condition register to a general register and to move
5563 ;; between the general registers and the floating point registers.
5564
5565 (define_insn "movcc"
5566 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5567 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5568 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5569 "* return mips_move_1word (operands, insn, FALSE);"
5570 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5571 (set_attr "mode" "SI")
5572 (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5573
5574 ;; Reload condition code registers. These need scratch registers.
5575
5576 (define_expand "reload_incc"
5577 [(set (match_operand:CC 0 "register_operand" "=z")
5578 (match_operand:CC 1 "general_operand" "z"))
5579 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5580 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5581 "
5582 {
5583 rtx source;
5584 rtx fp1, fp2;
5585
5586 /* This is called when are copying some value into a condition code
5587 register. Operand 0 is the condition code register. Operand 1
5588 is the source. Operand 2 is a scratch register; we use TFmode
5589 because we actually need two floating point registers. */
5590 if (! ST_REG_P (true_regnum (operands[0]))
5591 || ! FP_REG_P (true_regnum (operands[2])))
5592 abort ();
5593
5594 /* We need to get the source in SFmode so that the insn is
5595 recognized. */
5596 if (GET_CODE (operands[1]) == MEM)
5597 source = change_address (operands[1], SFmode, NULL_RTX);
5598 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5599 source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
5600 else
5601 source = operands[1];
5602
5603 fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
5604 fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
5605
5606 emit_insn (gen_move_insn (fp1, source));
5607 emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
5608 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
5609 gen_rtx (LT, CCmode, fp2, fp1)));
5610
5611 DONE;
5612 }")
5613
5614 (define_expand "reload_outcc"
5615 [(set (match_operand:CC 0 "general_operand" "=z")
5616 (match_operand:CC 1 "register_operand" "z"))
5617 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5618 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5619 "
5620 {
5621 /* This is called when we are copying a condition code register out
5622 to save it somewhere. Operand 0 should be the location we are
5623 going to save it to. Operand 1 should be the condition code
5624 register. Operand 2 should be a scratch general purpose register
5625 created for us by reload. The mips_secondary_reload_class
5626 function should have told reload that we don't need a scratch
5627 register if the destination is a general purpose register anyhow. */
5628 if (ST_REG_P (true_regnum (operands[0]))
5629 || GP_REG_P (true_regnum (operands[0]))
5630 || ! ST_REG_P (true_regnum (operands[1]))
5631 || ! GP_REG_P (true_regnum (operands[2])))
5632 abort ();
5633
5634 /* All we have to do is copy the value from the condition code to
5635 the data register, which movcc can handle, and then store the
5636 value into the real final destination. */
5637 emit_insn (gen_move_insn (operands[2], operands[1]));
5638 emit_insn (gen_move_insn (operands[0], operands[2]));
5639
5640 DONE;
5641 }")
5642
5643 ;; MIPS4 supports loading and storing a floating point register from
5644 ;; the sum of two general registers. We use two versions for each of
5645 ;; these four instructions: one where the two general registers are
5646 ;; SImode, and one where they are DImode. This is because general
5647 ;; registers will be in SImode when they hold 32 bit values, but,
5648 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5649 ;; instructions will still work correctly.
5650
5651 ;; ??? Perhaps it would be better to support these instructions by
5652 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5653 ;; these instructions can only be used to load and store floating
5654 ;; point registers, that would probably cause trouble in reload.
5655
5656 (define_insn ""
5657 [(set (match_operand:SF 0 "register_operand" "=f")
5658 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5659 (match_operand:SI 2 "register_operand" "d"))))]
5660 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5661 "lwxc1\\t%0,%1(%2)"
5662 [(set_attr "type" "load")
5663 (set_attr "mode" "SF")])
5664
5665 (define_insn ""
5666 [(set (match_operand:SF 0 "register_operand" "=f")
5667 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5668 (match_operand:DI 2 "se_register_operand" "d"))))]
5669 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5670 "lwxc1\\t%0,%1(%2)"
5671 [(set_attr "type" "load")
5672 (set_attr "mode" "SF")])
5673
5674 (define_insn ""
5675 [(set (match_operand:DF 0 "register_operand" "=f")
5676 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5677 (match_operand:SI 2 "register_operand" "d"))))]
5678 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5679 "ldxc1\\t%0,%1(%2)"
5680 [(set_attr "type" "load")
5681 (set_attr "mode" "DF")])
5682
5683 (define_insn ""
5684 [(set (match_operand:DF 0 "register_operand" "=f")
5685 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5686 (match_operand:DI 2 "se_register_operand" "d"))))]
5687 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5688 "ldxc1\\t%0,%1(%2)"
5689 [(set_attr "type" "load")
5690 (set_attr "mode" "DF")])
5691
5692 (define_insn ""
5693 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5694 (match_operand:SI 2 "register_operand" "d")))
5695 (match_operand:SF 0 "register_operand" "=f"))]
5696 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5697 "swxc1\\t%0,%1(%2)"
5698 [(set_attr "type" "store")
5699 (set_attr "mode" "SF")])
5700
5701 (define_insn ""
5702 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5703 (match_operand:DI 2 "se_register_operand" "d")))
5704 (match_operand:SF 0 "register_operand" "=f"))]
5705 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5706 "swxc1\\t%0,%1(%2)"
5707 [(set_attr "type" "store")
5708 (set_attr "mode" "SF")])
5709
5710 (define_insn ""
5711 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5712 (match_operand:SI 2 "register_operand" "d")))
5713 (match_operand:DF 0 "register_operand" "=f"))]
5714 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5715 "sdxc1\\t%0,%1(%2)"
5716 [(set_attr "type" "store")
5717 (set_attr "mode" "DF")])
5718
5719 (define_insn ""
5720 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5721 (match_operand:DI 2 "se_register_operand" "d")))
5722 (match_operand:DF 0 "register_operand" "=f"))]
5723 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5724 "sdxc1\\t%0,%1(%2)"
5725 [(set_attr "type" "store")
5726 (set_attr "mode" "DF")])
5727
5728 ;; 16-bit Integer moves
5729
5730 ;; Unlike most other insns, the move insns can't be split with
5731 ;; different predicates, because register spilling and other parts of
5732 ;; the compiler, have memoized the insn number already.
5733 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5734
5735 (define_expand "movhi"
5736 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5737 (match_operand:HI 1 "general_operand" ""))]
5738 ""
5739 "
5740 {
5741 if ((reload_in_progress | reload_completed) == 0
5742 && !register_operand (operands[0], HImode)
5743 && !register_operand (operands[1], HImode)
5744 && (TARGET_MIPS16
5745 || (GET_CODE (operands[1]) != CONST_INT
5746 || INTVAL (operands[1]) != 0)))
5747 {
5748 rtx temp = force_reg (HImode, operands[1]);
5749 emit_move_insn (operands[0], temp);
5750 DONE;
5751 }
5752 }")
5753
5754 ;; The difference between these two is whether or not ints are allowed
5755 ;; in FP registers (off by default, use -mdebugh to enable).
5756
5757 (define_insn "movhi_internal1"
5758 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5759 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5760 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5761 && (register_operand (operands[0], HImode)
5762 || register_operand (operands[1], HImode)
5763 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5764 "* return mips_move_1word (operands, insn, TRUE);"
5765 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5766 (set_attr "mode" "HI")
5767 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
5768
5769 (define_insn "movhi_internal2"
5770 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5771 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5772 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5773 && (register_operand (operands[0], HImode)
5774 || register_operand (operands[1], HImode)
5775 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5776 "* return mips_move_1word (operands, insn, TRUE);"
5777 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5778 (set_attr "mode" "HI")
5779 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
5780
5781 (define_insn ""
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5783 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5784 "TARGET_MIPS16
5785 && (register_operand (operands[0], HImode)
5786 || register_operand (operands[1], HImode))"
5787 "* return mips_move_1word (operands, insn, TRUE);"
5788 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5789 (set_attr "mode" "HI")
5790 (set_attr_alternative "length"
5791 [(const_int 4)
5792 (const_int 4)
5793 (const_int 4)
5794 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5795 (const_int 4)
5796 (const_int 8))
5797 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5798 (const_int 8)
5799 (const_int 12))
5800 (const_int 4)
5801 (const_int 8)
5802 (const_int 4)
5803 (const_int 8)
5804 (const_int 4)])])
5805
5806
5807 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
5808 ;; when the original load is a 4 byte instruction but the add and the
5809 ;; load are 2 2 byte instructions.
5810
5811 (define_split
5812 [(set (match_operand:HI 0 "register_operand" "")
5813 (mem:HI (plus:SI (match_dup 0)
5814 (match_operand:SI 1 "const_int_operand" ""))))]
5815 "TARGET_MIPS16 && reload_completed
5816 && GET_CODE (operands[0]) == REG
5817 && M16_REG_P (REGNO (operands[0]))
5818 && GET_CODE (operands[1]) == CONST_INT
5819 && ((INTVAL (operands[1]) < 0
5820 && INTVAL (operands[1]) >= -0x80)
5821 || (INTVAL (operands[1]) >= 32 * 2
5822 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5823 || (INTVAL (operands[1]) >= 0
5824 && INTVAL (operands[1]) < 32 * 2
5825 && (INTVAL (operands[1]) & 1) != 0))"
5826 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5827 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5828 "
5829 {
5830 HOST_WIDE_INT val = INTVAL (operands[1]);
5831
5832 if (val < 0)
5833 operands[2] = GEN_INT (0);
5834 else if (val >= 32 * 2)
5835 {
5836 int off = val & 1;
5837
5838 operands[1] = GEN_INT (0x7e + off);
5839 operands[2] = GEN_INT (val - off - 0x7e);
5840 }
5841 else
5842 {
5843 int off = val & 1;
5844
5845 operands[1] = GEN_INT (off);
5846 operands[2] = GEN_INT (val - off);
5847 }
5848 }")
5849
5850 ;; 8-bit Integer moves
5851
5852 ;; Unlike most other insns, the move insns can't be split with
5853 ;; different predicates, because register spilling and other parts of
5854 ;; the compiler, have memoized the insn number already.
5855 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5856
5857 (define_expand "movqi"
5858 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5859 (match_operand:QI 1 "general_operand" ""))]
5860 ""
5861 "
5862 {
5863 if ((reload_in_progress | reload_completed) == 0
5864 && !register_operand (operands[0], QImode)
5865 && !register_operand (operands[1], QImode)
5866 && (TARGET_MIPS16
5867 || (GET_CODE (operands[1]) != CONST_INT
5868 || INTVAL (operands[1]) != 0)))
5869 {
5870 rtx temp = force_reg (QImode, operands[1]);
5871 emit_move_insn (operands[0], temp);
5872 DONE;
5873 }
5874 }")
5875
5876 ;; The difference between these two is whether or not ints are allowed
5877 ;; in FP registers (off by default, use -mdebugh to enable).
5878
5879 (define_insn "movqi_internal1"
5880 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
5881 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5882 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5883 && (register_operand (operands[0], QImode)
5884 || register_operand (operands[1], QImode)
5885 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5886 "* return mips_move_1word (operands, insn, TRUE);"
5887 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5888 (set_attr "mode" "QI")
5889 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
5890
5891 (define_insn "movqi_internal2"
5892 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5893 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5894 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5895 && (register_operand (operands[0], QImode)
5896 || register_operand (operands[1], QImode)
5897 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5898 "* return mips_move_1word (operands, insn, TRUE);"
5899 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5900 (set_attr "mode" "QI")
5901 (set_attr "length" "4,4,4,8,4,8,4,4,4,4")])
5902
5903 (define_insn ""
5904 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5905 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5906 "TARGET_MIPS16
5907 && (register_operand (operands[0], QImode)
5908 || register_operand (operands[1], QImode))"
5909 "* return mips_move_1word (operands, insn, TRUE);"
5910 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5911 (set_attr "mode" "QI")
5912 (set_attr_alternative "length"
5913 [(const_int 4)
5914 (const_int 4)
5915 (const_int 4)
5916 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5917 (const_int 4)
5918 (const_int 8))
5919 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5920 (const_int 8)
5921 (const_int 12))
5922 (const_int 4)
5923 (const_int 8)
5924 (const_int 4)
5925 (const_int 8)
5926 (const_int 4)])])
5927
5928
5929 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5930 ;; when the original load is a 4 byte instruction but the add and the
5931 ;; load are 2 2 byte instructions.
5932
5933 (define_split
5934 [(set (match_operand:QI 0 "register_operand" "")
5935 (mem:QI (plus:SI (match_dup 0)
5936 (match_operand:SI 1 "const_int_operand" ""))))]
5937 "TARGET_MIPS16 && reload_completed
5938 && GET_CODE (operands[0]) == REG
5939 && M16_REG_P (REGNO (operands[0]))
5940 && GET_CODE (operands[1]) == CONST_INT
5941 && ((INTVAL (operands[1]) < 0
5942 && INTVAL (operands[1]) >= -0x80)
5943 || (INTVAL (operands[1]) >= 32
5944 && INTVAL (operands[1]) <= 31 + 0x7f))"
5945 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5946 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5947 "
5948 {
5949 HOST_WIDE_INT val = INTVAL (operands[1]);
5950
5951 if (val < 0)
5952 operands[2] = GEN_INT (0);
5953 else
5954 {
5955 operands[1] = GEN_INT (0x7f);
5956 operands[2] = GEN_INT (val - 0x7f);
5957 }
5958 }")
5959
5960 ;; 32-bit floating point moves
5961
5962 (define_expand "movsf"
5963 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5964 (match_operand:SF 1 "general_operand" ""))]
5965 ""
5966 "
5967 {
5968 if ((reload_in_progress | reload_completed) == 0
5969 && !register_operand (operands[0], SFmode)
5970 && !register_operand (operands[1], SFmode)
5971 && (TARGET_MIPS16
5972 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5973 && operands[1] != CONST0_RTX (SFmode))))
5974 {
5975 rtx temp = force_reg (SFmode, operands[1]);
5976 emit_move_insn (operands[0], temp);
5977 DONE;
5978 }
5979 }")
5980
5981 (define_insn "movsf_internal1"
5982 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
5983 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
5984 "TARGET_HARD_FLOAT
5985 && (register_operand (operands[0], SFmode)
5986 || register_operand (operands[1], SFmode)
5987 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5988 || operands[1] == CONST0_RTX (SFmode))"
5989 "* return mips_move_1word (operands, insn, FALSE);"
5990 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
5991 (set_attr "mode" "SF")
5992 (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
5993
5994
5995 (define_insn "movsf_internal2"
5996 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
5997 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
5998 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5999 && (register_operand (operands[0], SFmode)
6000 || register_operand (operands[1], SFmode)
6001 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6002 || operands[1] == CONST0_RTX (SFmode))"
6003 "* return mips_move_1word (operands, insn, FALSE);"
6004 [(set_attr "type" "move,load,load,store,store")
6005 (set_attr "mode" "SF")
6006 (set_attr "length" "4,4,8,4,8")])
6007
6008 (define_insn ""
6009 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6010 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
6011 "TARGET_MIPS16
6012 && (register_operand (operands[0], SFmode)
6013 || register_operand (operands[1], SFmode))"
6014 "* return mips_move_1word (operands, insn, FALSE);"
6015 [(set_attr "type" "move,move,move,load,load,store,store")
6016 (set_attr "mode" "SF")
6017 (set_attr "length" "4,4,4,4,8,4,8")])
6018
6019
6020 ;; 64-bit floating point moves
6021
6022 (define_expand "movdf"
6023 [(set (match_operand:DF 0 "nonimmediate_operand" "")
6024 (match_operand:DF 1 "general_operand" ""))]
6025 ""
6026 "
6027 {
6028 if ((reload_in_progress | reload_completed) == 0
6029 && !register_operand (operands[0], DFmode)
6030 && !register_operand (operands[1], DFmode)
6031 && (TARGET_MIPS16
6032 || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6033 && operands[1] != CONST0_RTX (DFmode))))
6034 {
6035 rtx temp = force_reg (DFmode, operands[1]);
6036 emit_move_insn (operands[0], temp);
6037 DONE;
6038 }
6039 }")
6040
6041 (define_insn "movdf_internal1"
6042 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6043 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6044 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6045 && TARGET_DOUBLE_FLOAT
6046 && (register_operand (operands[0], DFmode)
6047 || register_operand (operands[1], DFmode)
6048 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6049 || operands[1] == CONST0_RTX (DFmode))"
6050 "* return mips_move_2words (operands, insn); "
6051 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6052 (set_attr "mode" "DF")
6053 (set_attr "length" "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6054
6055 (define_insn "movdf_internal1a"
6056 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,f,*d,*d,*d,*To,*R")
6057 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,F,*F,*To,*R,*d,*d"))]
6058 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6059 && TARGET_DOUBLE_FLOAT
6060 && (register_operand (operands[0], DFmode)
6061 || register_operand (operands[1], DFmode)
6062 || (GET_CODE (operands [0]) == MEM
6063 && ((GET_CODE (operands[1]) == CONST_INT
6064 && INTVAL (operands[1]) == 0)
6065 || operands[1] == CONST0_RTX (DFmode))))"
6066 "* return mips_move_2words (operands, insn); "
6067 [(set_attr "type" "move,load,store,store,store,store,load,load,load,load,store,store")
6068 (set_attr "mode" "DF")
6069 (set_attr "length" "4,8,4,4,8,8,8,8,8,4,8,4")])
6070
6071 (define_insn "movdf_internal2"
6072 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To")
6073 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d"))]
6074 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6075 && (register_operand (operands[0], DFmode)
6076 || register_operand (operands[1], DFmode)
6077 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6078 || operands[1] == CONST0_RTX (DFmode))"
6079 "* return mips_move_2words (operands, insn); "
6080 [(set_attr "type" "move,load,load,store,store")
6081 (set_attr "mode" "DF")
6082 (set_attr "length" "8,8,16,8,16")])
6083
6084 (define_insn ""
6085 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6086 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6087 "TARGET_MIPS16
6088 && (register_operand (operands[0], DFmode)
6089 || register_operand (operands[1], DFmode))"
6090 "* return mips_move_2words (operands, insn);"
6091 [(set_attr "type" "move,move,move,load,load,store,store")
6092 (set_attr "mode" "DF")
6093 (set_attr "length" "8,8,8,8,16,8,16")])
6094
6095 (define_split
6096 [(set (match_operand:DF 0 "register_operand" "")
6097 (match_operand:DF 1 "register_operand" ""))]
6098 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6099 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6100 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6101 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6102 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
6103 "")
6104
6105 ;; Instructions to load the global pointer register.
6106 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6107 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
6108
6109 (define_insn "loadgp"
6110 [(set (reg:DI 28)
6111 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6112 (match_operand:DI 1 "register_operand" "")] 2))
6113 (clobber (reg:DI 1))]
6114 ""
6115 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6116 [(set_attr "type" "move")
6117 (set_attr "mode" "DI")
6118 (set_attr "length" "12")])
6119 \f
6120 ;; Block moves, see mips.c for more details.
6121 ;; Argument 0 is the destination
6122 ;; Argument 1 is the source
6123 ;; Argument 2 is the length
6124 ;; Argument 3 is the alignment
6125
6126 (define_expand "movstrsi"
6127 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6128 (match_operand:BLK 1 "general_operand" ""))
6129 (use (match_operand:SI 2 "arith32_operand" ""))
6130 (use (match_operand:SI 3 "immediate_operand" ""))])]
6131 "!TARGET_MIPS16"
6132 "
6133 {
6134 if (operands[0]) /* avoid unused code messages */
6135 {
6136 expand_block_move (operands);
6137 DONE;
6138 }
6139 }")
6140
6141 ;; Insn generated by block moves
6142
6143 (define_insn "movstrsi_internal"
6144 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6145 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6146 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6147 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6148 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6149 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6150 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6151 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6152 (use (const_int 0))] ;; normal block move
6153 ""
6154 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6155 [(set_attr "type" "store")
6156 (set_attr "mode" "none")
6157 (set_attr "length" "80")])
6158
6159 ;; We need mips16 versions, because an offset from the stack pointer
6160 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6161 ;; byte loads.
6162
6163 (define_insn ""
6164 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6165 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6166 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6167 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6168 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6169 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6170 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6171 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6172 (use (const_int 0))] ;; normal block move
6173 "TARGET_MIPS16"
6174 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6175 [(set_attr "type" "multi")
6176 (set_attr "mode" "none")
6177 (set_attr "length" "80")])
6178
6179 (define_insn ""
6180 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6181 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6182 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6183 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6184 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6185 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6186 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6187 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6188 (use (const_int 0))] ;; normal block move
6189 "TARGET_MIPS16"
6190 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6191 [(set_attr "type" "multi")
6192 (set_attr "mode" "none")
6193 (set_attr "length" "80")])
6194
6195 (define_insn ""
6196 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6197 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6198 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6199 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6200 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6201 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6202 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6203 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6204 (use (const_int 0))] ;; normal block move
6205 "TARGET_MIPS16"
6206 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6207 [(set_attr "type" "multi")
6208 (set_attr "mode" "none")
6209 (set_attr "length" "80")])
6210
6211 ;; Split a block move into 2 parts, the first part is everything
6212 ;; except for the last move, and the second part is just the last
6213 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6214 ;; fill a delay slot. This also prevents a bug in delayed branches
6215 ;; from showing up, which reuses one of the registers in our clobbers.
6216
6217 (define_split
6218 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6219 (mem:BLK (match_operand:SI 1 "register_operand" "")))
6220 (clobber (match_operand:SI 4 "register_operand" ""))
6221 (clobber (match_operand:SI 5 "register_operand" ""))
6222 (clobber (match_operand:SI 6 "register_operand" ""))
6223 (clobber (match_operand:SI 7 "register_operand" ""))
6224 (use (match_operand:SI 2 "small_int" ""))
6225 (use (match_operand:SI 3 "small_int" ""))
6226 (use (const_int 0))]
6227
6228 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6229
6230 ;; All but the last move
6231 [(parallel [(set (mem:BLK (match_dup 0))
6232 (mem:BLK (match_dup 1)))
6233 (clobber (match_dup 4))
6234 (clobber (match_dup 5))
6235 (clobber (match_dup 6))
6236 (clobber (match_dup 7))
6237 (use (match_dup 2))
6238 (use (match_dup 3))
6239 (use (const_int 1))])
6240
6241 ;; The last store, so it can fill a delay slot
6242 (parallel [(set (mem:BLK (match_dup 0))
6243 (mem:BLK (match_dup 1)))
6244 (clobber (match_dup 4))
6245 (clobber (match_dup 5))
6246 (clobber (match_dup 6))
6247 (clobber (match_dup 7))
6248 (use (match_dup 2))
6249 (use (match_dup 3))
6250 (use (const_int 2))])]
6251
6252 "")
6253
6254 (define_insn "movstrsi_internal2"
6255 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
6256 (match_operand:BLK 1 "memory_operand" "o")) ;; source
6257 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6258 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6259 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6260 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6261 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6262 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6263 (use (const_int 1))] ;; all but last store
6264 ""
6265 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6266 [(set_attr "type" "store")
6267 (set_attr "mode" "none")
6268 (set_attr "length" "80")])
6269
6270 (define_insn ""
6271 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6272 (match_operand:BLK 1 "memory_operand" "d")) ;; source
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 "TARGET_MIPS16"
6281 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6282 [(set_attr "type" "multi")
6283 (set_attr "mode" "none")
6284 (set_attr "length" "80")])
6285
6286 (define_insn "movstrsi_internal3"
6287 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
6288 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
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 2))] ;; just last store of block move
6296 ""
6297 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6298 [(set_attr "type" "store")
6299 (set_attr "mode" "none")])
6300
6301 (define_insn ""
6302 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
6303 (match_operand:BLK 1 "memory_operand" "d")) ;; source
6304 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
6305 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
6306 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
6307 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
6308 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
6309 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
6310 (use (const_int 2))] ;; just last store of block move
6311 "TARGET_MIPS16"
6312 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6313 [(set_attr "type" "store")
6314 (set_attr "mode" "none")])
6315
6316 \f
6317 ;;
6318 ;; ....................
6319 ;;
6320 ;; SHIFTS
6321 ;;
6322 ;; ....................
6323
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"
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 ""
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"
6363 "*
6364 {
6365 if (GET_CODE (operands[2]) == CONST_INT)
6366 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6367
6368 return \"sll\\t%0,%1,%2\";
6369 }"
6370 [(set_attr "type" "arith")
6371 (set_attr "mode" "SI")])
6372
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)
6384 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6385
6386 return \"sll\\t%0,%1,%2\";
6387 }"
6388 [(set_attr "type" "arith")
6389 (set_attr "mode" "SI")
6390 (set_attr_alternative "length"
6391 [(const_int 4)
6392 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6393 (const_int 4)
6394 (const_int 8))])])
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 }")
6413
6414 (define_expand "ashldi3"
6415 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6416 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6417 (match_operand:SI 2 "arith_operand" "")))
6418 (clobber (match_dup 3))])]
6419 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6420 "
6421 {
6422 if (TARGET_64BIT)
6423 {
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
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 }")
6454
6455
6456 (define_insn "ashldi3_internal"
6457 [(set (match_operand:DI 0 "register_operand" "=&d")
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"))]
6461 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
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\\
6474 %~1:\\n\\
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\\
6481 %~2:\\n\\
6482 \\tsll\\t%L0,%L1,%2\\n\\
6483 %~3:\";
6484 }"
6485 [(set_attr "type" "darith")
6486 (set_attr "mode" "SI")
6487 (set_attr "length" "48")])
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"))]
6495 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6496 && (INTVAL (operands[2]) & 32) != 0"
6497 "*
6498 {
6499 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
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")
6505 (set_attr "length" "8")])
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" ""))]
6513 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6514 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
6519 [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6520 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6521
6522 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
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" ""))]
6530 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6531 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
6536 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6537 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6538
6539 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
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"))]
6547 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6548 && (INTVAL (operands[2]) & 63) < 32
6549 && (INTVAL (operands[2]) & 63) != 0"
6550 "*
6551 {
6552 int amount = INTVAL (operands[2]);
6553
6554 operands[2] = GEN_INT ((amount & 31));
6555 operands[4] = const0_rtx;
6556 operands[5] = GEN_INT (((-amount) & 31));
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")
6562 (set_attr "length" "16")])
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" ""))]
6570 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6571 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
6577 [(set (subreg:SI (match_dup 0) 1)
6578 (ashift:SI (subreg:SI (match_dup 1) 1)
6579 (match_dup 2)))
6580
6581 (set (match_dup 3)
6582 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6583 (match_dup 4)))
6584
6585 (set (subreg:SI (match_dup 0) 1)
6586 (ior:SI (subreg:SI (match_dup 0) 1)
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]);
6595 operands[2] = GEN_INT ((amount & 31));
6596 operands[4] = GEN_INT (((-amount) & 31));
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" ""))]
6605 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6606 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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)
6617 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
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
6624 (set (subreg:SI (match_dup 0) 1)
6625 (ashift:SI (subreg:SI (match_dup 1) 1)
6626 (match_dup 2)))]
6627 "
6628 {
6629 int amount = INTVAL (operands[2]);
6630 operands[2] = GEN_INT ((amount & 31));
6631 operands[4] = GEN_INT (((-amount) & 31));
6632 }")
6633
6634
6635 (define_insn "ashldi3_internal4"
6636 [(set (match_operand:DI 0 "register_operand" "=d")
6637 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6638 (match_operand:SI 2 "arith_operand" "dI")))]
6639 "TARGET_64BIT && !TARGET_MIPS16"
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")
6648 (set_attr "mode" "DI")])
6649
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"
6668 [(const_int 4)
6669 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6670 (const_int 4)
6671 (const_int 8))])])
6672
6673
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"
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 ""
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"
6724 "*
6725 {
6726 if (GET_CODE (operands[2]) == CONST_INT)
6727 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6728
6729 return \"sra\\t%0,%1,%2\";
6730 }"
6731 [(set_attr "type" "arith")
6732 (set_attr "mode" "SI")])
6733
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)
6745 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6746
6747 return \"sra\\t%0,%1,%2\";
6748 }"
6749 [(set_attr "type" "arith")
6750 (set_attr "mode" "SI")
6751 (set_attr_alternative "length"
6752 [(const_int 4)
6753 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6754 (const_int 4)
6755 (const_int 8))])])
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 }")
6775
6776 (define_expand "ashrdi3"
6777 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6778 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6779 (match_operand:SI 2 "arith_operand" "")))
6780 (clobber (match_dup 3))])]
6781 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6782 "
6783 {
6784 if (TARGET_64BIT)
6785 {
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
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 }")
6812
6813
6814 (define_insn "ashrdi3_internal"
6815 [(set (match_operand:DI 0 "register_operand" "=&d")
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"))]
6819 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
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\\
6832 %~1:\\n\\
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\\
6839 %~2:\\n\\
6840 \\tsra\\t%M0,%M1,%2\\n\\
6841 %~3:\";
6842 }"
6843 [(set_attr "type" "darith")
6844 (set_attr "mode" "DI")
6845 (set_attr "length" "48")])
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"))]
6853 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
6854 "*
6855 {
6856 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6857 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6858 }"
6859 [(set_attr "type" "darith")
6860 (set_attr "mode" "DI")
6861 (set_attr "length" "8")])
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" ""))]
6869 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
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
6874 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6875 (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
6876
6877 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
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" ""))]
6885 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
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
6890 [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6891 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6892
6893 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
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"))]
6901 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6902 && (INTVAL (operands[2]) & 63) < 32
6903 && (INTVAL (operands[2]) & 63) != 0"
6904 "*
6905 {
6906 int amount = INTVAL (operands[2]);
6907
6908 operands[2] = GEN_INT ((amount & 31));
6909 operands[4] = GEN_INT (((-amount) & 31));
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")
6915 (set_attr "length" "16")])
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" ""))]
6923 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6924 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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)
6935 (ashift:SI (subreg:SI (match_dup 1) 1)
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
6942 (set (subreg:SI (match_dup 0) 1)
6943 (ashiftrt:SI (subreg:SI (match_dup 1) 1)
6944 (match_dup 2)))]
6945 "
6946 {
6947 int amount = INTVAL (operands[2]);
6948 operands[2] = GEN_INT ((amount & 31));
6949 operands[4] = GEN_INT (((-amount) & 31));
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" ""))]
6958 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6959 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
6965 [(set (subreg:SI (match_dup 0) 1)
6966 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6967 (match_dup 2)))
6968
6969 (set (match_dup 3)
6970 (ashift:SI (subreg:SI (match_dup 1) 0)
6971 (match_dup 4)))
6972
6973 (set (subreg:SI (match_dup 0) 1)
6974 (ior:SI (subreg:SI (match_dup 0) 1)
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]);
6983 operands[2] = GEN_INT ((amount & 31));
6984 operands[4] = GEN_INT (((-amount) & 31));
6985 }")
6986
6987
6988 (define_insn "ashrdi3_internal4"
6989 [(set (match_operand:DI 0 "register_operand" "=d")
6990 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6991 (match_operand:SI 2 "arith_operand" "dI")))]
6992 "TARGET_64BIT && !TARGET_MIPS16"
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")
7001 (set_attr "mode" "DI")])
7002
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"
7018 [(const_int 4)
7019 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7020 (const_int 4)
7021 (const_int 8))])])
7022
7023 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7024
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"
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 ""
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"
7073 "*
7074 {
7075 if (GET_CODE (operands[2]) == CONST_INT)
7076 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7077
7078 return \"srl\\t%0,%1,%2\";
7079 }"
7080 [(set_attr "type" "arith")
7081 (set_attr "mode" "SI")])
7082
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)
7094 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7095
7096 return \"srl\\t%0,%1,%2\";
7097 }"
7098 [(set_attr "type" "arith")
7099 (set_attr "mode" "SI")
7100 (set_attr_alternative "length"
7101 [(const_int 4)
7102 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7103 (const_int 4)
7104 (const_int 8))])])
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 ""
7133 [(set (match_operand:SI 0 "register_operand" "=d,d")
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" "")
7142 (const_int 8)
7143 (const_int 12))
7144 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7145 (const_int 12)
7146 (const_int 16))])])
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 "")
7156
7157 (define_expand "lshrdi3"
7158 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7159 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7160 (match_operand:SI 2 "arith_operand" "")))
7161 (clobber (match_dup 3))])]
7162 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7163 "
7164 {
7165 if (TARGET_64BIT)
7166 {
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
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 }")
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"))]
7200 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
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\\
7213 %~1:\\n\\
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\\
7220 %~2:\\n\\
7221 \\tsrl\\t%M0,%M1,%2\\n\\
7222 %~3:\";
7223 }"
7224 [(set_attr "type" "darith")
7225 (set_attr "mode" "DI")
7226 (set_attr "length" "48")])
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"))]
7234 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7235 && (INTVAL (operands[2]) & 32) != 0"
7236 "*
7237 {
7238 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
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")
7244 (set_attr "length" "8")])
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" ""))]
7252 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7253 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
7258 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
7259 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
7260
7261 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
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" ""))]
7269 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7270 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
7275 [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7276 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7277
7278 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
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"))]
7286 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7287 && (INTVAL (operands[2]) & 63) < 32
7288 && (INTVAL (operands[2]) & 63) != 0"
7289 "*
7290 {
7291 int amount = INTVAL (operands[2]);
7292
7293 operands[2] = GEN_INT ((amount & 31));
7294 operands[4] = GEN_INT (((-amount) & 31));
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")
7300 (set_attr "length" "16")])
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" ""))]
7308 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7309 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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)
7320 (ashift:SI (subreg:SI (match_dup 1) 1)
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
7327 (set (subreg:SI (match_dup 0) 1)
7328 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
7329 (match_dup 2)))]
7330 "
7331 {
7332 int amount = INTVAL (operands[2]);
7333 operands[2] = GEN_INT ((amount & 31));
7334 operands[4] = GEN_INT (((-amount) & 31));
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" ""))]
7343 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7344 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
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
7350 [(set (subreg:SI (match_dup 0) 1)
7351 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
7352 (match_dup 2)))
7353
7354 (set (match_dup 3)
7355 (ashift:SI (subreg:SI (match_dup 1) 0)
7356 (match_dup 4)))
7357
7358 (set (subreg:SI (match_dup 0) 1)
7359 (ior:SI (subreg:SI (match_dup 0) 1)
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]);
7368 operands[2] = GEN_INT ((amount & 31));
7369 operands[4] = GEN_INT (((-amount) & 31));
7370 }")
7371
7372
7373 (define_insn "lshrdi3_internal4"
7374 [(set (match_operand:DI 0 "register_operand" "=d")
7375 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7376 (match_operand:SI 2 "arith_operand" "dI")))]
7377 "TARGET_64BIT && !TARGET_MIPS16"
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")
7386 (set_attr "mode" "DI")])
7387
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"
7403 [(const_int 4)
7404 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7405 (const_int 4)
7406 (const_int 8))])])
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
7426 \f
7427 ;;
7428 ;; ....................
7429 ;;
7430 ;; COMPARISONS
7431 ;;
7432 ;; ....................
7433
7434 ;; Flow here is rather complex:
7435 ;;
7436 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
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
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.
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
7481 (define_expand "cmpdi"
7482 [(set (cc0)
7483 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7484 (match_operand:DI 1 "se_arith_operand" "")))]
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)
7499 (match_operand:DI 0 "se_register_operand" ""))]
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
7512 (define_expand "cmpdf"
7513 [(set (cc0)
7514 (compare:CC (match_operand:DF 0 "register_operand" "")
7515 (match_operand:DF 1 "register_operand" "")))]
7516 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
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
7528 (define_expand "cmpsf"
7529 [(set (cc0)
7530 (compare:CC (match_operand:SF 0 "register_operand" "")
7531 (match_operand:SF 1 "register_operand" "")))]
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
7544 \f
7545 ;;
7546 ;; ....................
7547 ;;
7548 ;; CONDITIONAL BRANCHES
7549 ;;
7550 ;; ....................
7551
7552 ;; Conditional branches on floating-point equality tests.
7553
7554 (define_insn "branch_fp"
7555 [(set (pc)
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)))]
7562 "TARGET_HARD_FLOAT"
7563 "*
7564 {
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));
7571 }"
7572 [(set_attr "type" "branch")
7573 (set_attr "mode" "none")])
7574
7575 (define_insn "branch_fp_inverted"
7576 [(set (pc)
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 "" ""))))]
7583 "TARGET_HARD_FLOAT"
7584 "*
7585 {
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));
7592 }"
7593 [(set_attr "type" "branch")
7594 (set_attr "mode" "none")])
7595
7596 ;; Conditional branches on comparisons with zero.
7597
7598 (define_insn "branch_zero"
7599 [(set (pc)
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)))]
7606 "!TARGET_MIPS16"
7607 "*
7608 {
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")])
7618
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")])
7639
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));
7657 }"
7658 [(set_attr "type" "branch")
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")])
7767
7768 ;; MIPS16 branches
7769
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")
7797 (set_attr "length" "8")])
7798
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")
7826 (set_attr "length" "8")])
7827
7828 (define_expand "beq"
7829 [(set (pc)
7830 (if_then_else (eq:CC (cc0)
7831 (const_int 0))
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)
7846 (if_then_else (ne:CC (cc0)
7847 (const_int 0))
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")
7999 (eq:SI (match_dup 1)
8000 (match_dup 2)))]
8001 ""
8002 "
8003 {
8004 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8005 FAIL;
8006
8007 /* set up operands from compare. */
8008 operands[1] = branch_cmp[0];
8009 operands[2] = branch_cmp[1];
8010
8011 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8012 {
8013 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8014 DONE;
8015 }
8016
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
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)))]
8028 "!TARGET_MIPS16"
8029 "sltu\\t%0,%1,1"
8030 [(set_attr "type" "arith")
8031 (set_attr "mode" "SI")])
8032
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")
8040 (set_attr "mode" "SI")])
8041
8042 (define_insn "seq_di_zero"
8043 [(set (match_operand:DI 0 "register_operand" "=d")
8044 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8045 (const_int 0)))]
8046 "TARGET_64BIT && !TARGET_MIPS16"
8047 "sltu\\t%0,%1,1"
8048 [(set_attr "type" "arith")
8049 (set_attr "mode" "DI")])
8050
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")
8058 (set_attr "mode" "DI")])
8059
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")))]
8064 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8065 "@
8066 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8067 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8068 [(set_attr "type" "arith")
8069 (set_attr "mode" "SI")
8070 (set_attr "length" "8")])
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" "")))]
8076 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
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")
8088 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8089 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8090 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
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")
8096 (set_attr "length" "8")])
8097
8098 (define_split
8099 [(set (match_operand:DI 0 "register_operand" "")
8100 (eq:DI (match_operand:DI 1 "se_register_operand" "")
8101 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8102 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8103 && !TARGET_MIPS16
8104 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8105 [(set (match_dup 0)
8106 (xor:DI (match_dup 1)
8107 (match_dup 2)))
8108 (set (match_dup 0)
8109 (ltu:DI (match_dup 0)
8110 (const_int 1)))]
8111 "")
8112
8113 ;; On the mips16 the default code is better than using sltu.
8114
8115 (define_expand "sne"
8116 [(set (match_operand:SI 0 "register_operand" "=d")
8117 (ne:SI (match_dup 1)
8118 (match_dup 2)))]
8119 "!TARGET_MIPS16"
8120 "
8121 {
8122 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8123 FAIL;
8124
8125 /* set up operands from compare. */
8126 operands[1] = branch_cmp[0];
8127 operands[2] = branch_cmp[1];
8128
8129 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8130 {
8131 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8132 DONE;
8133 }
8134
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
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)))]
8145 "!TARGET_MIPS16"
8146 "sltu\\t%0,%.,%1"
8147 [(set_attr "type" "arith")
8148 (set_attr "mode" "SI")])
8149
8150 (define_insn "sne_di_zero"
8151 [(set (match_operand:DI 0 "register_operand" "=d")
8152 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8153 (const_int 0)))]
8154 "TARGET_64BIT && !TARGET_MIPS16"
8155 "sltu\\t%0,%.,%1"
8156 [(set_attr "type" "arith")
8157 (set_attr "mode" "DI")])
8158
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")))]
8163 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8164 "@
8165 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8166 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8167 [(set_attr "type" "arith")
8168 (set_attr "mode" "SI")
8169 (set_attr "length" "8")])
8170
8171 (define_split
8172 [(set (match_operand:SI 0 "register_operand" "")
8173 (ne:SI (match_operand:SI 1 "register_operand" "")
8174 (match_operand:SI 2 "uns_arith_operand" "")))]
8175 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8176 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8177 [(set (match_dup 0)
8178 (xor:SI (match_dup 1)
8179 (match_dup 2)))
8180 (set (match_dup 0)
8181 (gtu:SI (match_dup 0)
8182 (const_int 0)))]
8183 "")
8184
8185 (define_insn "sne_di"
8186 [(set (match_operand:DI 0 "register_operand" "=d,d")
8187 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8188 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8189 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
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")
8195 (set_attr "length" "8")])
8196
8197 (define_split
8198 [(set (match_operand:DI 0 "register_operand" "")
8199 (ne:DI (match_operand:DI 1 "se_register_operand" "")
8200 (match_operand:DI 2 "se_uns_arith_operand" "")))]
8201 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8202 && !TARGET_MIPS16
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
8212 (define_expand "sgt"
8213 [(set (match_operand:SI 0 "register_operand" "=d")
8214 (gt:SI (match_dup 1)
8215 (match_dup 2)))]
8216 ""
8217 "
8218 {
8219 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8220 FAIL;
8221
8222 /* set up operands from compare. */
8223 operands[1] = branch_cmp[0];
8224 operands[2] = branch_cmp[1];
8225
8226 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8227 {
8228 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8229 DONE;
8230 }
8231
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")
8240 (gt:SI (match_operand:SI 1 "register_operand" "d")
8241 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8242 "!TARGET_MIPS16"
8243 "slt\\t%0,%z2,%1"
8244 [(set_attr "type" "arith")
8245 (set_attr "mode" "SI")])
8246
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")
8254 (set_attr "mode" "SI")])
8255
8256 (define_insn "sgt_di"
8257 [(set (match_operand:DI 0 "register_operand" "=d")
8258 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8259 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8260 "TARGET_64BIT && !TARGET_MIPS16"
8261 "slt\\t%0,%z2,%1"
8262 [(set_attr "type" "arith")
8263 (set_attr "mode" "DI")])
8264
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")
8272 (set_attr "mode" "DI")])
8273
8274 (define_expand "sge"
8275 [(set (match_operand:SI 0 "register_operand" "=d")
8276 (ge:SI (match_dup 1)
8277 (match_dup 2)))]
8278 ""
8279 "
8280 {
8281 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8282 FAIL;
8283
8284 /* set up operands from compare. */
8285 operands[1] = branch_cmp[0];
8286 operands[2] = branch_cmp[1];
8287
8288 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8289 {
8290 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8291 DONE;
8292 }
8293
8294 /* fall through and generate default code */
8295 }")
8296
8297 (define_insn "sge_si"
8298 [(set (match_operand:SI 0 "register_operand" "=d")
8299 (ge:SI (match_operand:SI 1 "register_operand" "d")
8300 (match_operand:SI 2 "arith_operand" "dI")))]
8301 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8302 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8303 [(set_attr "type" "arith")
8304 (set_attr "mode" "SI")
8305 (set_attr "length" "8")])
8306
8307 (define_split
8308 [(set (match_operand:SI 0 "register_operand" "")
8309 (ge:SI (match_operand:SI 1 "register_operand" "")
8310 (match_operand:SI 2 "arith_operand" "")))]
8311 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8312 [(set (match_dup 0)
8313 (lt:SI (match_dup 1)
8314 (match_dup 2)))
8315 (set (match_dup 0)
8316 (xor:SI (match_dup 0)
8317 (const_int 1)))]
8318 "")
8319
8320 (define_insn "sge_di"
8321 [(set (match_operand:DI 0 "register_operand" "=d")
8322 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8323 (match_operand:DI 2 "se_arith_operand" "dI")))]
8324 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8325 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8326 [(set_attr "type" "arith")
8327 (set_attr "mode" "DI")
8328 (set_attr "length" "8")])
8329
8330 (define_split
8331 [(set (match_operand:DI 0 "register_operand" "")
8332 (ge:DI (match_operand:DI 1 "se_register_operand" "")
8333 (match_operand:DI 2 "se_arith_operand" "")))]
8334 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8335 && !TARGET_MIPS16"
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
8344 (define_expand "slt"
8345 [(set (match_operand:SI 0 "register_operand" "=d")
8346 (lt:SI (match_dup 1)
8347 (match_dup 2)))]
8348 ""
8349 "
8350 {
8351 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8352 FAIL;
8353
8354 /* set up operands from compare. */
8355 operands[1] = branch_cmp[0];
8356 operands[2] = branch_cmp[1];
8357
8358 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8359 {
8360 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8361 DONE;
8362 }
8363
8364 /* fall through and generate default code */
8365 }")
8366
8367 (define_insn "slt_si"
8368 [(set (match_operand:SI 0 "register_operand" "=d")
8369 (lt:SI (match_operand:SI 1 "register_operand" "d")
8370 (match_operand:SI 2 "arith_operand" "dI")))]
8371 "!TARGET_MIPS16"
8372 "slt\\t%0,%1,%2"
8373 [(set_attr "type" "arith")
8374 (set_attr "mode" "SI")])
8375
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"
8385 [(const_int 4)
8386 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8387 (const_int 4)
8388 (const_int 8))])])
8389
8390 (define_insn "slt_di"
8391 [(set (match_operand:DI 0 "register_operand" "=d")
8392 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8393 (match_operand:DI 2 "se_arith_operand" "dI")))]
8394 "TARGET_64BIT && !TARGET_MIPS16"
8395 "slt\\t%0,%1,%2"
8396 [(set_attr "type" "arith")
8397 (set_attr "mode" "DI")])
8398
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"
8408 [(const_int 4)
8409 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8410 (const_int 4)
8411 (const_int 8))])])
8412
8413 (define_expand "sle"
8414 [(set (match_operand:SI 0 "register_operand" "=d")
8415 (le:SI (match_dup 1)
8416 (match_dup 2)))]
8417 ""
8418 "
8419 {
8420 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8421 FAIL;
8422
8423 /* set up operands from compare. */
8424 operands[1] = branch_cmp[0];
8425 operands[2] = branch_cmp[1];
8426
8427 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8428 {
8429 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8430 DONE;
8431 }
8432
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
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")))]
8443 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8444 "*
8445 {
8446 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8447 return \"slt\\t%0,%1,%2\";
8448 }"
8449 [(set_attr "type" "arith")
8450 (set_attr "mode" "SI")])
8451
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 {
8459 operands[2] = GEN_INT (INTVAL (operands[2])+1);
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" "")
8465 (const_int 4)
8466 (const_int 8)))])
8467
8468 (define_insn "sle_di_const"
8469 [(set (match_operand:DI 0 "register_operand" "=d")
8470 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8471 (match_operand:DI 2 "small_int" "I")))]
8472 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8473 "*
8474 {
8475 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8476 return \"slt\\t%0,%1,%2\";
8477 }"
8478 [(set_attr "type" "arith")
8479 (set_attr "mode" "DI")])
8480
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 {
8488 operands[2] = GEN_INT (INTVAL (operands[2])+1);
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" "")
8494 (const_int 4)
8495 (const_int 8)))])
8496
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")))]
8501 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8502 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8503 [(set_attr "type" "arith")
8504 (set_attr "mode" "SI")
8505 (set_attr "length" "8")])
8506
8507 (define_split
8508 [(set (match_operand:SI 0 "register_operand" "")
8509 (le:SI (match_operand:SI 1 "register_operand" "")
8510 (match_operand:SI 2 "register_operand" "")))]
8511 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8512 [(set (match_dup 0)
8513 (lt:SI (match_dup 2)
8514 (match_dup 1)))
8515 (set (match_dup 0)
8516 (xor:SI (match_dup 0)
8517 (const_int 1)))]
8518 "")
8519
8520 (define_insn "sle_di_reg"
8521 [(set (match_operand:DI 0 "register_operand" "=d")
8522 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8523 (match_operand:DI 2 "se_register_operand" "d")))]
8524 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8525 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8526 [(set_attr "type" "arith")
8527 (set_attr "mode" "DI")
8528 (set_attr "length" "8")])
8529
8530 (define_split
8531 [(set (match_operand:DI 0 "register_operand" "")
8532 (le:DI (match_operand:DI 1 "se_register_operand" "")
8533 (match_operand:DI 2 "se_register_operand" "")))]
8534 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8535 && !TARGET_MIPS16"
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
8544 (define_expand "sgtu"
8545 [(set (match_operand:SI 0 "register_operand" "=d")
8546 (gtu:SI (match_dup 1)
8547 (match_dup 2)))]
8548 ""
8549 "
8550 {
8551 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8552 FAIL;
8553
8554 /* set up operands from compare. */
8555 operands[1] = branch_cmp[0];
8556 operands[2] = branch_cmp[1];
8557
8558 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8559 {
8560 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8561 DONE;
8562 }
8563
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")
8572 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8573 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8574 ""
8575 "sltu\\t%0,%z2,%1"
8576 [(set_attr "type" "arith")
8577 (set_attr "mode" "SI")])
8578
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")
8586 (set_attr "mode" "SI")])
8587
8588 (define_insn "sgtu_di"
8589 [(set (match_operand:DI 0 "register_operand" "=d")
8590 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8591 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8592 "TARGET_64BIT"
8593 "sltu\\t%0,%z2,%1"
8594 [(set_attr "type" "arith")
8595 (set_attr "mode" "DI")])
8596
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")
8604 (set_attr "mode" "DI")])
8605
8606 (define_expand "sgeu"
8607 [(set (match_operand:SI 0 "register_operand" "=d")
8608 (geu:SI (match_dup 1)
8609 (match_dup 2)))]
8610 ""
8611 "
8612 {
8613 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8614 FAIL;
8615
8616 /* set up operands from compare. */
8617 operands[1] = branch_cmp[0];
8618 operands[2] = branch_cmp[1];
8619
8620 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8621 {
8622 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8623 DONE;
8624 }
8625
8626 /* fall through and generate default code */
8627 }")
8628
8629 (define_insn "sgeu_si"
8630 [(set (match_operand:SI 0 "register_operand" "=d")
8631 (geu:SI (match_operand:SI 1 "register_operand" "d")
8632 (match_operand:SI 2 "arith_operand" "dI")))]
8633 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8634 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8635 [(set_attr "type" "arith")
8636 (set_attr "mode" "SI")
8637 (set_attr "length" "8")])
8638
8639 (define_split
8640 [(set (match_operand:SI 0 "register_operand" "")
8641 (geu:SI (match_operand:SI 1 "register_operand" "")
8642 (match_operand:SI 2 "arith_operand" "")))]
8643 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8644 [(set (match_dup 0)
8645 (ltu:SI (match_dup 1)
8646 (match_dup 2)))
8647 (set (match_dup 0)
8648 (xor:SI (match_dup 0)
8649 (const_int 1)))]
8650 "")
8651
8652 (define_insn "sgeu_di"
8653 [(set (match_operand:DI 0 "register_operand" "=d")
8654 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8655 (match_operand:DI 2 "se_arith_operand" "dI")))]
8656 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8657 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8658 [(set_attr "type" "arith")
8659 (set_attr "mode" "DI")
8660 (set_attr "length" "8")])
8661
8662 (define_split
8663 [(set (match_operand:DI 0 "register_operand" "")
8664 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8665 (match_operand:DI 2 "se_arith_operand" "")))]
8666 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8667 && !TARGET_MIPS16"
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
8676 (define_expand "sltu"
8677 [(set (match_operand:SI 0 "register_operand" "=d")
8678 (ltu:SI (match_dup 1)
8679 (match_dup 2)))]
8680 ""
8681 "
8682 {
8683 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8684 FAIL;
8685
8686 /* set up operands from compare. */
8687 operands[1] = branch_cmp[0];
8688 operands[2] = branch_cmp[1];
8689
8690 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8691 {
8692 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8693 DONE;
8694 }
8695
8696 /* fall through and generate default code */
8697 }")
8698
8699 (define_insn "sltu_si"
8700 [(set (match_operand:SI 0 "register_operand" "=d")
8701 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8702 (match_operand:SI 2 "arith_operand" "dI")))]
8703 "!TARGET_MIPS16"
8704 "sltu\\t%0,%1,%2"
8705 [(set_attr "type" "arith")
8706 (set_attr "mode" "SI")])
8707
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"
8717 [(const_int 4)
8718 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8719 (const_int 4)
8720 (const_int 8))])])
8721
8722 (define_insn "sltu_di"
8723 [(set (match_operand:DI 0 "register_operand" "=d")
8724 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8725 (match_operand:DI 2 "se_arith_operand" "dI")))]
8726 "TARGET_64BIT && !TARGET_MIPS16"
8727 "sltu\\t%0,%1,%2"
8728 [(set_attr "type" "arith")
8729 (set_attr "mode" "DI")])
8730
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"
8740 [(const_int 4)
8741 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8742 (const_int 4)
8743 (const_int 8))])])
8744
8745 (define_expand "sleu"
8746 [(set (match_operand:SI 0 "register_operand" "=d")
8747 (leu:SI (match_dup 1)
8748 (match_dup 2)))]
8749 ""
8750 "
8751 {
8752 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8753 FAIL;
8754
8755 /* set up operands from compare. */
8756 operands[1] = branch_cmp[0];
8757 operands[2] = branch_cmp[1];
8758
8759 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8760 {
8761 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8762 DONE;
8763 }
8764
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
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")))]
8775 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8776 "*
8777 {
8778 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8779 return \"sltu\\t%0,%1,%2\";
8780 }"
8781 [(set_attr "type" "arith")
8782 (set_attr "mode" "SI")])
8783
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 {
8791 operands[2] = GEN_INT (INTVAL (operands[2])+1);
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" "")
8797 (const_int 4)
8798 (const_int 8)))])
8799
8800 (define_insn "sleu_di_const"
8801 [(set (match_operand:DI 0 "register_operand" "=d")
8802 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8803 (match_operand:DI 2 "small_int" "I")))]
8804 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8805 "*
8806 {
8807 operands[2] = GEN_INT (INTVAL (operands[2])+1);
8808 return \"sltu\\t%0,%1,%2\";
8809 }"
8810 [(set_attr "type" "arith")
8811 (set_attr "mode" "DI")])
8812
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 {
8820 operands[2] = GEN_INT (INTVAL (operands[2])+1);
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" "")
8826 (const_int 4)
8827 (const_int 8)))])
8828
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")))]
8833 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8834 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8835 [(set_attr "type" "arith")
8836 (set_attr "mode" "SI")
8837 (set_attr "length" "8")])
8838
8839 (define_split
8840 [(set (match_operand:SI 0 "register_operand" "")
8841 (leu:SI (match_operand:SI 1 "register_operand" "")
8842 (match_operand:SI 2 "register_operand" "")))]
8843 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8844 [(set (match_dup 0)
8845 (ltu:SI (match_dup 2)
8846 (match_dup 1)))
8847 (set (match_dup 0)
8848 (xor:SI (match_dup 0)
8849 (const_int 1)))]
8850 "")
8851
8852 (define_insn "sleu_di_reg"
8853 [(set (match_operand:DI 0 "register_operand" "=d")
8854 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8855 (match_operand:DI 2 "se_register_operand" "d")))]
8856 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8857 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8858 [(set_attr "type" "arith")
8859 (set_attr "mode" "DI")
8860 (set_attr "length" "8")])
8861
8862 (define_split
8863 [(set (match_operand:DI 0 "register_operand" "")
8864 (leu:DI (match_operand:DI 1 "se_register_operand" "")
8865 (match_operand:DI 2 "se_register_operand" "")))]
8866 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8867 && !TARGET_MIPS16"
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
8876 \f
8877 ;;
8878 ;; ....................
8879 ;;
8880 ;; FLOATING POINT COMPARISONS
8881 ;;
8882 ;; ....................
8883
8884 (define_insn "seq_df"
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")))]
8888 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8889 "*
8890 {
8891 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8892 }"
8893 [(set_attr "type" "fcmp")
8894 (set_attr "mode" "FPSW")])
8895
8896 (define_insn "slt_df"
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")))]
8900 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8901 "*
8902 {
8903 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8904 }"
8905 [(set_attr "type" "fcmp")
8906 (set_attr "mode" "FPSW")])
8907
8908 (define_insn "sle_df"
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")))]
8912 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8913 "*
8914 {
8915 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8916 }"
8917 [(set_attr "type" "fcmp")
8918 (set_attr "mode" "FPSW")])
8919
8920 (define_insn "sgt_df"
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")))]
8924 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8925 "*
8926 {
8927 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8928 }"
8929 [(set_attr "type" "fcmp")
8930 (set_attr "mode" "FPSW")])
8931
8932 (define_insn "sge_df"
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")))]
8936 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8937 "*
8938 {
8939 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8940 }"
8941 [(set_attr "type" "fcmp")
8942 (set_attr "mode" "FPSW")])
8943
8944 (define_insn "seq_sf"
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")))]
8948 "TARGET_HARD_FLOAT"
8949 "*
8950 {
8951 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8952 }"
8953 [(set_attr "type" "fcmp")
8954 (set_attr "mode" "FPSW")])
8955
8956 (define_insn "slt_sf"
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")))]
8960 "TARGET_HARD_FLOAT"
8961 "*
8962 {
8963 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8964 }"
8965 [(set_attr "type" "fcmp")
8966 (set_attr "mode" "FPSW")])
8967
8968 (define_insn "sle_sf"
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")))]
8972 "TARGET_HARD_FLOAT"
8973 "*
8974 {
8975 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8976 }"
8977 [(set_attr "type" "fcmp")
8978 (set_attr "mode" "FPSW")])
8979
8980 (define_insn "sgt_sf"
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")))]
8984 "TARGET_HARD_FLOAT"
8985 "*
8986 {
8987 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8988 }"
8989 [(set_attr "type" "fcmp")
8990 (set_attr "mode" "FPSW")])
8991
8992 (define_insn "sge_sf"
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")))]
8996 "TARGET_HARD_FLOAT"
8997 "*
8998 {
8999 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9000 }"
9001 [(set_attr "type" "fcmp")
9002 (set_attr "mode" "FPSW")])
9003
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 "" "")))]
9017 "!TARGET_MIPS16"
9018 "*
9019 {
9020 if (GET_CODE (operands[0]) == REG)
9021 return \"%*j\\t%0\";
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. */
9025 else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9026 return \"%*b\\t%l0\";
9027 else
9028 return \"%*j\\t%l0\";
9029 }"
9030 [(set_attr "type" "jump")
9031 (set_attr "mode" "none")])
9032
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")
9043 (set_attr "length" "8")])
9044
9045 (define_expand "indirect_jump"
9046 [(set (pc) (match_operand 0 "register_operand" "d"))]
9047 ""
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
9058 if (!(Pmode == DImode))
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"))]
9069 "!(Pmode == DImode)"
9070 "%*j\\t%0"
9071 [(set_attr "type" "jump")
9072 (set_attr "mode" "none")])
9073
9074 (define_insn "indirect_jump_internal2"
9075 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9076 "Pmode == DImode"
9077 "%*j\\t%0"
9078 [(set_attr "type" "jump")
9079 (set_attr "mode" "none")])
9080
9081 (define_expand "tablejump"
9082 [(set (pc)
9083 (match_operand 0 "register_operand" "d"))
9084 (use (label_ref (match_operand 1 "" "")))]
9085 ""
9086 "
9087 {
9088 if (operands[0]) /* eliminate unused code warnings */
9089 {
9090 if (TARGET_MIPS16)
9091 {
9092 if (GET_MODE (operands[0]) != HImode)
9093 abort ();
9094 if (!(Pmode == DImode))
9095 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9096 else
9097 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9098 DONE;
9099 }
9100
9101 if (GET_MODE (operands[0]) != Pmode)
9102 abort ();
9103
9104 if (! flag_pic)
9105 {
9106 if (!(Pmode == DImode))
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 }
9111 else
9112 {
9113 if (!(Pmode == DImode))
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 }
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 "" "")))]
9127 "!(Pmode == DImode)"
9128 "%*j\\t%0"
9129 [(set_attr "type" "jump")
9130 (set_attr "mode" "none")])
9131
9132 (define_insn "tablejump_internal2"
9133 [(set (pc)
9134 (match_operand:DI 0 "se_register_operand" "d"))
9135 (use (label_ref (match_operand 1 "" "")))]
9136 "Pmode == DImode"
9137 "%*j\\t%0"
9138 [(set_attr "type" "jump")
9139 (set_attr "mode" "none")])
9140
9141 (define_expand "tablejump_internal3"
9142 [(parallel [(set (pc)
9143 (plus:SI (match_operand:SI 0 "register_operand" "d")
9144 (label_ref:SI (match_operand:SI 1 "" ""))))
9145 (use (label_ref:SI (match_dup 1)))])]
9146 ""
9147 "")
9148
9149 (define_expand "tablejump_mips161"
9150 [(set (pc) (plus:SI (sign_extend:SI
9151 (match_operand:HI 0 "register_operand" "d"))
9152 (label_ref:SI (match_operand:SI 1 "" ""))))]
9153 "TARGET_MIPS16 && !(Pmode == DImode)"
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));
9166 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
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"))
9174 (label_ref:DI (match_operand:SI 1 "" ""))))]
9175 "TARGET_MIPS16 && Pmode == DImode"
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));
9188 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9189 DONE;
9190 }
9191 }")
9192
9193 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9194 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9195 ;;; any longer.
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")
9203 (label_ref:SI (match_operand:SI 1 "" ""))))
9204 (use (label_ref:SI (match_dup 1)))]
9205 "!(Pmode == DImode) && next_active_insn (insn) != 0
9206 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9207 && PREV_INSN (next_active_insn (insn)) == operands[1]"
9208 "*
9209 {
9210 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
9211 if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9212 output_asm_insn (\".cpadd\\t%0\", operands);
9213 return \"%*j\\t%0\";
9214 }"
9215 [(set_attr "type" "jump")
9216 (set_attr "mode" "none")
9217 (set_attr "length" "8")])
9218
9219 (define_expand "tablejump_internal4"
9220 [(parallel [(set (pc)
9221 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9222 (label_ref:DI (match_operand:SI 1 "" ""))))
9223 (use (label_ref:DI (match_dup 1)))])]
9224 ""
9225 "")
9226
9227 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
9228 ;;; it is not valid. ??? With the USE, the condition tests may not be required
9229 ;;; any longer.
9230
9231 (define_insn ""
9232 [(set (pc)
9233 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9234 (label_ref:DI (match_operand:SI 1 "" ""))))
9235 (use (label_ref:DI (match_dup 1)))]
9236 "Pmode == DImode && next_active_insn (insn) != 0
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")
9241 (set_attr "mode" "none")])
9242
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 {
9268 /* We need slightly different code for eight byte table entries. */
9269 if (Pmode == DImode)
9270 abort ();
9271
9272 if (operands[0])
9273 {
9274 rtx reg = gen_reg_rtx (SImode);
9275
9276 /* If the index is too large, go to the default label. */
9277 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9278 emit_insn (gen_cmpsi (reg, operands[2]));
9279 emit_insn (gen_bgtu (operands[4]));
9280
9281 /* Do the PIC jump. */
9282 emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
9283
9284 DONE;
9285 }
9286 }")
9287
9288 ;; An embedded PIC switch statement looks like this:
9289 ;; bal $LS1
9290 ;; sll $reg,$index,2
9291 ;; $LS1:
9292 ;; addu $reg,$reg,$31
9293 ;; lw $reg,$L1-$LS1($reg)
9294 ;; addu $reg,$reg,$31
9295 ;; j $reg
9296 ;; $L1:
9297 ;; .word case1-$LS1
9298 ;; .word case2-$LS1
9299 ;; ...
9300
9301 (define_insn "casesi_internal"
9302 [(set (pc)
9303 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9304 (const_int 4))
9305 (label_ref (match_operand 1 "" "")))))
9306 (clobber (match_operand:SI 2 "register_operand" "d"))
9307 (clobber (reg:SI 31))]
9308 "TARGET_EMBEDDED_PIC"
9309 "*
9310 {
9311 output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%~%S1:\", operands);
9312 output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
9313 output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
9314 return \"j\\t%0\";
9315 }"
9316 [(set_attr "type" "jump")
9317 (set_attr "mode" "none")
9318 (set_attr "length" "24")])
9319
9320 ;; For o32/n32/n64, we save the gp in the jmp_buf as well. While it is
9321 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9322 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9323 ;; this is easy.
9324
9325 (define_expand "builtin_setjmp_setup"
9326 [(unspec [(match_operand 0 "register_operand" "r")] 20)]
9327 "TARGET_ABICALLS"
9328 "
9329 {
9330 if (Pmode == DImode)
9331 emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9332 else
9333 emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9334 DONE;
9335 }")
9336
9337 (define_expand "builtin_setjmp_setup_32"
9338 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9339 (const_int 12)))
9340 (reg:SI 28))]
9341 "TARGET_ABICALLS && ! (Pmode == DImode)"
9342 "")
9343
9344 (define_expand "builtin_setjmp_setup_64"
9345 [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9346 (const_int 24)))
9347 (reg:DI 28))]
9348 "TARGET_ABICALLS && Pmode == DImode"
9349 "")
9350
9351 ;; For o32/n32/n64, we need to arrange for longjmp to put the
9352 ;; target address in t9 so that we can use it for loading $gp.
9353
9354 (define_expand "builtin_longjmp"
9355 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
9356 "TARGET_ABICALLS"
9357 "
9358 {
9359 /* The elements of the buffer are, in order: */
9360 int W = (Pmode == DImode ? 8 : 4);
9361 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9362 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9363 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9364 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9365 rtx pv = gen_rtx_REG (Pmode, 25);
9366 rtx gp = gen_rtx_REG (Pmode, 28);
9367
9368 /* This bit is the same as expand_builtin_longjmp. */
9369 emit_move_insn (hard_frame_pointer_rtx, fp);
9370 emit_move_insn (pv, lab);
9371 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9372 emit_move_insn (gp, gpv);
9373 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9374 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9375 emit_insn (gen_rtx_USE (VOIDmode, gp));
9376 emit_indirect_jump (pv);
9377 DONE;
9378 }")
9379 \f
9380 ;;
9381 ;; ....................
9382 ;;
9383 ;; Function prologue/epilogue
9384 ;;
9385 ;; ....................
9386 ;;
9387
9388 (define_expand "prologue"
9389 [(const_int 1)]
9390 ""
9391 "
9392 {
9393 if (mips_isa >= 0) /* avoid unused code warnings */
9394 {
9395 mips_expand_prologue ();
9396 DONE;
9397 }
9398 }")
9399
9400 ;; Block any insns from being moved before this point, since the
9401 ;; profiling call to mcount can use various registers that aren't
9402 ;; saved or used to pass arguments.
9403
9404 (define_insn "blockage"
9405 [(unspec_volatile [(const_int 0)] 0)]
9406 ""
9407 ""
9408 [(set_attr "type" "unknown")
9409 (set_attr "mode" "none")
9410 (set_attr "length" "0")])
9411
9412 (define_expand "epilogue"
9413 [(const_int 2)]
9414 ""
9415 "
9416 {
9417 if (mips_isa >= 0) /* avoid unused code warnings */
9418 {
9419 mips_expand_epilogue ();
9420 DONE;
9421 }
9422 }")
9423
9424 ;; Trivial return. Make it look like a normal return insn as that
9425 ;; allows jump optimizations to work better .
9426 (define_insn "return"
9427 [(return)]
9428 "mips_can_use_return_insn ()"
9429 "%*j\\t$31"
9430 [(set_attr "type" "jump")
9431 (set_attr "mode" "none")])
9432
9433 ;; Normal return.
9434 ;; We match any mode for the return address, so that this will work with
9435 ;; both 32 bit and 64 bit targets.
9436 (define_insn "return_internal"
9437 [(use (match_operand 0 "register_operand" ""))
9438 (return)]
9439 ""
9440 "*
9441 {
9442 return \"%*j\\t%0\";
9443 }"
9444 [(set_attr "type" "jump")
9445 (set_attr "mode" "none")])
9446
9447 ;; When generating embedded PIC code we need to get the address of the
9448 ;; current function. This specialized instruction does just that.
9449
9450 (define_insn "get_fnaddr"
9451 [(set (match_operand 0 "register_operand" "=d")
9452 (unspec [(match_operand 1 "" "")] 1))
9453 (clobber (reg:SI 31))]
9454 "TARGET_EMBEDDED_PIC
9455 && GET_CODE (operands[1]) == SYMBOL_REF"
9456 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9457 [(set_attr "type" "call")
9458 (set_attr "mode" "none")
9459 (set_attr "length" "16")])
9460
9461 \f
9462 ;;
9463 ;; ....................
9464 ;;
9465 ;; FUNCTION CALLS
9466 ;;
9467 ;; ....................
9468
9469 ;; calls.c now passes a third argument, make saber happy
9470
9471 (define_expand "call"
9472 [(parallel [(call (match_operand 0 "memory_operand" "m")
9473 (match_operand 1 "" "i"))
9474 (clobber (reg:SI 31))
9475 (use (match_operand 2 "" "")) ;; next_arg_reg
9476 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
9477 ""
9478 "
9479 {
9480 rtx addr;
9481
9482 if (operands[0]) /* eliminate unused code warnings */
9483 {
9484 addr = XEXP (operands[0], 0);
9485 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9486 || ! call_insn_operand (addr, VOIDmode))
9487 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9488
9489 /* In order to pass small structures by value in registers
9490 compatibly with the MIPS compiler, we need to shift the value
9491 into the high part of the register. Function_arg has encoded
9492 a PARALLEL rtx, holding a vector of adjustments to be made
9493 as the next_arg_reg variable, so we split up the insns,
9494 and emit them separately. */
9495
9496 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9497 {
9498 rtvec adjust = XVEC (operands[2], 0);
9499 int num = GET_NUM_ELEM (adjust);
9500 int i;
9501
9502 for (i = 0; i < num; i++)
9503 emit_insn (RTVEC_ELT (adjust, i));
9504 }
9505
9506 if (TARGET_MIPS16
9507 && mips16_hard_float
9508 && operands[2] != 0
9509 && (int) GET_MODE (operands[2]) != 0)
9510 {
9511 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9512 (int) GET_MODE (operands[2])))
9513 DONE;
9514 }
9515
9516 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9517 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9518
9519 DONE;
9520 }
9521 }")
9522
9523 (define_expand "call_internal0"
9524 [(parallel [(call (match_operand 0 "" "")
9525 (match_operand 1 "" ""))
9526 (clobber (match_operand:SI 2 "" ""))])]
9527 ""
9528 "")
9529
9530 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9531 ;; don't have a constraint letter for it.
9532
9533 (define_insn ""
9534 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9535 (match_operand 1 "" "i"))
9536 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9537 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9538 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9539 "%*jal\\t%0"
9540 [(set_attr "type" "call")
9541 (set_attr "mode" "none")
9542 (set_attr "length" "8")])
9543
9544 (define_insn "call_internal1"
9545 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9546 (match_operand 1 "" "i"))
9547 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9548 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9549 "*
9550 {
9551 register rtx target = operands[0];
9552
9553 if (GET_CODE (target) == SYMBOL_REF)
9554 return \"%*jal\\t%0\";
9555 else if (GET_CODE (target) == CONST_INT)
9556 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9557 else
9558 return \"%*jal\\t%2,%0\";
9559 }"
9560 [(set_attr "type" "call")
9561 (set_attr "mode" "none")])
9562
9563 (define_insn "call_internal2"
9564 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9565 (match_operand 1 "" "i"))
9566 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9567 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9568 "*
9569 {
9570 register rtx target = operands[0];
9571
9572 if (GET_CODE (target) == SYMBOL_REF)
9573 {
9574 if (GET_MODE (target) == SImode)
9575 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9576 else
9577 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9578 }
9579 else if (GET_CODE (target) == CONST_INT)
9580 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9581 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9582 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9583 else
9584 return \"jal\\t%2,%0\";
9585 }"
9586 [(set_attr "type" "call")
9587 (set_attr "mode" "none")
9588 (set_attr "length" "8")])
9589
9590 (define_insn "call_internal3a"
9591 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9592 (match_operand 1 "" "i"))
9593 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9594 "!(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9595 "%*jal\\t%2,%0"
9596 [(set_attr "type" "call")
9597 (set_attr "mode" "none")])
9598
9599 (define_insn "call_internal3b"
9600 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9601 (match_operand 1 "" "i"))
9602 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9603 "Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9604 "%*jal\\t%2,%0"
9605 [(set_attr "type" "call")
9606 (set_attr "mode" "none")])
9607
9608 (define_insn "call_internal4a"
9609 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9610 (match_operand 1 "" "i"))
9611 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9612 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9613 "*
9614 {
9615 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9616 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9617 else
9618 return \"jal\\t%2,%0\";
9619 }"
9620 [(set_attr "type" "call")
9621 (set_attr "mode" "none")
9622 (set_attr "length" "8")])
9623
9624 (define_insn "call_internal4b"
9625 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9626 (match_operand 1 "" "i"))
9627 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9628 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9629 "*
9630 {
9631 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9632 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9633 else
9634 return \"jal\\t%2,%0\";
9635 }"
9636 [(set_attr "type" "call")
9637 (set_attr "mode" "none")
9638 (set_attr "length" "8")])
9639
9640 ;; calls.c now passes a fourth argument, make saber happy
9641
9642 (define_expand "call_value"
9643 [(parallel [(set (match_operand 0 "register_operand" "=df")
9644 (call (match_operand 1 "memory_operand" "m")
9645 (match_operand 2 "" "i")))
9646 (clobber (reg:SI 31))
9647 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9648 ""
9649 "
9650 {
9651 rtx addr;
9652
9653 if (operands[0]) /* eliminate unused code warning */
9654 {
9655 addr = XEXP (operands[1], 0);
9656 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9657 || ! call_insn_operand (addr, VOIDmode))
9658 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9659
9660 /* In order to pass small structures by value in registers
9661 compatibly with the MIPS compiler, we need to shift the value
9662 into the high part of the register. Function_arg has encoded
9663 a PARALLEL rtx, holding a vector of adjustments to be made
9664 as the next_arg_reg variable, so we split up the insns,
9665 and emit them separately. */
9666
9667 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9668 {
9669 rtvec adjust = XVEC (operands[3], 0);
9670 int num = GET_NUM_ELEM (adjust);
9671 int i;
9672
9673 for (i = 0; i < num; i++)
9674 emit_insn (RTVEC_ELT (adjust, i));
9675 }
9676
9677 if (TARGET_MIPS16
9678 && mips16_hard_float
9679 && ((operands[3] != 0
9680 && (int) GET_MODE (operands[3]) != 0)
9681 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9682 {
9683 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9684 (operands[3] == 0 ? 0
9685 : (int) GET_MODE (operands[3]))))
9686 DONE;
9687 }
9688
9689 /* Handle Irix6 function calls that have multiple non-contiguous
9690 results. */
9691 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9692 {
9693 emit_call_insn (gen_call_value_multiple_internal0
9694 (XEXP (XVECEXP (operands[0], 0, 0), 0),
9695 operands[1], operands[2],
9696 XEXP (XVECEXP (operands[0], 0, 1), 0),
9697 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9698 DONE;
9699 }
9700
9701 /* We have a call returning a DImode structure in an FP reg.
9702 Strip off the now unnecessary PARALLEL. */
9703 if (GET_CODE (operands[0]) == PARALLEL)
9704 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9705
9706 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9707 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9708
9709 DONE;
9710 }
9711 }")
9712
9713 (define_expand "call_value_internal0"
9714 [(parallel [(set (match_operand 0 "" "")
9715 (call (match_operand 1 "" "")
9716 (match_operand 2 "" "")))
9717 (clobber (match_operand:SI 3 "" ""))])]
9718 ""
9719 "")
9720
9721 ;; Recognize $31 specially on the mips16, because we don't have a
9722 ;; constraint letter for it.
9723
9724 (define_insn ""
9725 [(set (match_operand 0 "register_operand" "=d")
9726 (call (mem (match_operand 1 "call_insn_operand" "ei"))
9727 (match_operand 2 "" "i")))
9728 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9729 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9730 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9731 "%*jal\\t%1"
9732 [(set_attr "type" "call")
9733 (set_attr "mode" "none")
9734 (set_attr "length" "8")])
9735
9736 (define_insn "call_value_internal1"
9737 [(set (match_operand 0 "register_operand" "=df")
9738 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9739 (match_operand 2 "" "i")))
9740 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9741 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9742 "*
9743 {
9744 register rtx target = operands[1];
9745
9746 if (GET_CODE (target) == SYMBOL_REF)
9747 return \"%*jal\\t%1\";
9748 else if (GET_CODE (target) == CONST_INT)
9749 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
9750 else
9751 return \"%*jal\\t%3,%1\";
9752 }"
9753 [(set_attr "type" "call")
9754 (set_attr "mode" "none")])
9755
9756 (define_insn "call_value_internal2"
9757 [(set (match_operand 0 "register_operand" "=df")
9758 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9759 (match_operand 2 "" "i")))
9760 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9761 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9762 "*
9763 {
9764 register rtx target = operands[1];
9765
9766 if (GET_CODE (target) == SYMBOL_REF)
9767 {
9768 if (GET_MODE (target) == SImode)
9769 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
9770 else
9771 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
9772 }
9773 else if (GET_CODE (target) == CONST_INT)
9774 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
9775 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9776 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9777 else
9778 return \"jal\\t%3,%1\";
9779 }"
9780 [(set_attr "type" "call")
9781 (set_attr "mode" "none")
9782 (set_attr "length" "8")])
9783
9784 (define_insn "call_value_internal3a"
9785 [(set (match_operand 0 "register_operand" "=df")
9786 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9787 (match_operand 2 "" "i")))
9788 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9789 "!TARGET_MIPS16
9790 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9791 "%*jal\\t%3,%1"
9792 [(set_attr "type" "call")
9793 (set_attr "mode" "none")])
9794
9795 (define_insn "call_value_internal3b"
9796 [(set (match_operand 0 "register_operand" "=df")
9797 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9798 (match_operand 2 "" "i")))
9799 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9800 "!TARGET_MIPS16
9801 && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9802 "%*jal\\t%3,%1"
9803 [(set_attr "type" "call")
9804 (set_attr "mode" "none")])
9805
9806 (define_insn "call_value_internal3c"
9807 [(set (match_operand 0 "register_operand" "=df")
9808 (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
9809 (match_operand 2 "" "i")))
9810 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9811 "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9812 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9813 "%*jal\\t%3,%1"
9814 [(set_attr "type" "call")
9815 (set_attr "mode" "none")])
9816
9817 (define_insn "call_value_internal4a"
9818 [(set (match_operand 0 "register_operand" "=df")
9819 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9820 (match_operand 2 "" "i")))
9821 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9822 "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9823 "*
9824 {
9825 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9826 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9827 else
9828 return \"jal\\t%3,%1\";
9829 }"
9830 [(set_attr "type" "call")
9831 (set_attr "mode" "none")
9832 (set_attr "length" "8")])
9833
9834 (define_insn "call_value_internal4b"
9835 [(set (match_operand 0 "register_operand" "=df")
9836 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9837 (match_operand 2 "" "i")))
9838 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9839 "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9840 "*
9841 {
9842 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9843 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9844 else
9845 return \"jal\\t%3,%1\";
9846 }"
9847 [(set_attr "type" "call")
9848 (set_attr "mode" "none")
9849 (set_attr "length" "8")])
9850
9851 (define_expand "call_value_multiple_internal0"
9852 [(parallel [(set (match_operand 0 "" "")
9853 (call (match_operand 1 "" "")
9854 (match_operand 2 "" "")))
9855 (set (match_operand 3 "" "")
9856 (call (match_dup 1)
9857 (match_dup 2)))
9858 (clobber (match_operand:SI 4 "" ""))])]
9859 ""
9860 "")
9861
9862 ;; ??? May eventually need all 6 versions of the call patterns with multiple
9863 ;; return values.
9864
9865 (define_insn "call_value_multiple_internal2"
9866 [(set (match_operand 0 "register_operand" "=df")
9867 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9868 (match_operand 2 "" "i")))
9869 (set (match_operand 3 "register_operand" "=df")
9870 (call (mem (match_dup 1))
9871 (match_dup 2)))
9872 (clobber (match_operand:SI 4 "register_operand" "=d"))]
9873 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9874 "*
9875 {
9876 register rtx target = operands[1];
9877
9878 if (GET_CODE (target) == SYMBOL_REF)
9879 {
9880 if (GET_MODE (target) == SImode)
9881 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9882 else
9883 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9884 }
9885 else if (GET_CODE (target) == CONST_INT)
9886 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
9887 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9888 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
9889 else
9890 return \"jal\\t%4,%1\";
9891 }"
9892 [(set_attr "type" "call")
9893 (set_attr "mode" "none")
9894 (set_attr "length" "8")])
9895
9896
9897 ;; Call subroutine returning any type.
9898
9899 (define_expand "untyped_call"
9900 [(parallel [(call (match_operand 0 "" "")
9901 (const_int 0))
9902 (match_operand 1 "" "")
9903 (match_operand 2 "" "")])]
9904 ""
9905 "
9906 {
9907 if (operands[0]) /* silence statement not reached warnings */
9908 {
9909 int i;
9910
9911 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
9912
9913 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9914 {
9915 rtx set = XVECEXP (operands[2], 0, i);
9916 emit_move_insn (SET_DEST (set), SET_SRC (set));
9917 }
9918
9919 emit_insn (gen_blockage ());
9920 DONE;
9921 }
9922 }")
9923 \f
9924 ;;
9925 ;; ....................
9926 ;;
9927 ;; MISC.
9928 ;;
9929 ;; ....................
9930 ;;
9931
9932 (define_insn "nop"
9933 [(const_int 0)]
9934 ""
9935 "%(nop%)"
9936 [(set_attr "type" "nop")
9937 (set_attr "mode" "none")])
9938
9939 ;; The MIPS chip does not seem to require stack probes.
9940 ;;
9941 ;; (define_expand "probe"
9942 ;; [(set (match_dup 0)
9943 ;; (match_dup 1))]
9944 ;; ""
9945 ;; "
9946 ;; {
9947 ;; operands[0] = gen_reg_rtx (SImode);
9948 ;; operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
9949 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
9950 ;;
9951 ;; /* fall through and generate default code */
9952 ;; }")
9953 ;;
9954 \f
9955 ;;
9956 ;; MIPS4 Conditional move instructions.
9957
9958 (define_insn ""
9959 [(set (match_operand:SI 0 "register_operand" "=d,d")
9960 (if_then_else:SI
9961 (match_operator 4 "equality_op"
9962 [(match_operand:SI 1 "register_operand" "d,d")
9963 (const_int 0)])
9964 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9965 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9966 "mips_isa >= 4"
9967 "@
9968 mov%B4\\t%0,%z2,%1
9969 mov%b4\\t%0,%z3,%1"
9970 [(set_attr "type" "move")
9971 (set_attr "mode" "SI")])
9972
9973 (define_insn ""
9974 [(set (match_operand:SI 0 "register_operand" "=d,d")
9975 (if_then_else:SI
9976 (match_operator 4 "equality_op"
9977 [(match_operand:DI 1 "se_register_operand" "d,d")
9978 (const_int 0)])
9979 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9980 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9981 "mips_isa >= 4"
9982 "@
9983 mov%B4\\t%0,%z2,%1
9984 mov%b4\\t%0,%z3,%1"
9985 [(set_attr "type" "move")
9986 (set_attr "mode" "SI")])
9987
9988 (define_insn ""
9989 [(set (match_operand:SI 0 "register_operand" "=d,d")
9990 (if_then_else:SI
9991 (match_operator 3 "equality_op" [(match_operand:CC 4
9992 "register_operand"
9993 "z,z")
9994 (const_int 0)])
9995 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
9996 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
9997 "mips_isa >= 4 && TARGET_HARD_FLOAT"
9998 "@
9999 mov%T3\\t%0,%z1,%4
10000 mov%t3\\t%0,%z2,%4"
10001 [(set_attr "type" "move")
10002 (set_attr "mode" "SI")])
10003
10004 (define_insn ""
10005 [(set (match_operand:DI 0 "register_operand" "=d,d")
10006 (if_then_else:DI
10007 (match_operator 4 "equality_op"
10008 [(match_operand:SI 1 "register_operand" "d,d")
10009 (const_int 0)])
10010 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10011 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10012 "mips_isa >= 4"
10013 "@
10014 mov%B4\\t%0,%z2,%1
10015 mov%b4\\t%0,%z3,%1"
10016 [(set_attr "type" "move")
10017 (set_attr "mode" "DI")])
10018
10019 (define_insn ""
10020 [(set (match_operand:DI 0 "register_operand" "=d,d")
10021 (if_then_else:DI
10022 (match_operator 4 "equality_op"
10023 [(match_operand:DI 1 "se_register_operand" "d,d")
10024 (const_int 0)])
10025 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10026 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10027 "mips_isa >= 4"
10028 "@
10029 mov%B4\\t%0,%z2,%1
10030 mov%b4\\t%0,%z3,%1"
10031 [(set_attr "type" "move")
10032 (set_attr "mode" "DI")])
10033
10034 (define_insn ""
10035 [(set (match_operand:DI 0 "register_operand" "=d,d")
10036 (if_then_else:DI
10037 (match_operator 3 "equality_op" [(match_operand:CC 4
10038 "register_operand"
10039 "z,z")
10040 (const_int 0)])
10041 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10042 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10043 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10044 "@
10045 mov%T3\\t%0,%z1,%4
10046 mov%t3\\t%0,%z2,%4"
10047 [(set_attr "type" "move")
10048 (set_attr "mode" "DI")])
10049
10050 (define_insn ""
10051 [(set (match_operand:SF 0 "register_operand" "=f,f")
10052 (if_then_else:SF
10053 (match_operator 4 "equality_op"
10054 [(match_operand:SI 1 "register_operand" "d,d")
10055 (const_int 0)])
10056 (match_operand:SF 2 "register_operand" "f,0")
10057 (match_operand:SF 3 "register_operand" "0,f")))]
10058 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10059 "@
10060 mov%B4.s\\t%0,%2,%1
10061 mov%b4.s\\t%0,%3,%1"
10062 [(set_attr "type" "move")
10063 (set_attr "mode" "SF")])
10064
10065 (define_insn ""
10066 [(set (match_operand:SF 0 "register_operand" "=f,f")
10067 (if_then_else:SF
10068 (match_operator 3 "equality_op" [(match_operand:CC 4
10069 "register_operand"
10070 "z,z")
10071 (const_int 0)])
10072 (match_operand:SF 1 "register_operand" "f,0")
10073 (match_operand:SF 2 "register_operand" "0,f")))]
10074 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10075 "@
10076 mov%T3.s\\t%0,%1,%4
10077 mov%t3.s\\t%0,%2,%4"
10078 [(set_attr "type" "move")
10079 (set_attr "mode" "SF")])
10080
10081 (define_insn ""
10082 [(set (match_operand:DF 0 "register_operand" "=f,f")
10083 (if_then_else:DF
10084 (match_operator 4 "equality_op"
10085 [(match_operand:SI 1 "register_operand" "d,d")
10086 (const_int 0)])
10087 (match_operand:DF 2 "register_operand" "f,0")
10088 (match_operand:DF 3 "register_operand" "0,f")))]
10089 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10090 "@
10091 mov%B4.d\\t%0,%2,%1
10092 mov%b4.d\\t%0,%3,%1"
10093 [(set_attr "type" "move")
10094 (set_attr "mode" "DF")])
10095
10096 (define_insn ""
10097 [(set (match_operand:DF 0 "register_operand" "=f,f")
10098 (if_then_else:DF
10099 (match_operator 3 "equality_op" [(match_operand:CC 4
10100 "register_operand"
10101 "z,z")
10102 (const_int 0)])
10103 (match_operand:DF 1 "register_operand" "f,0")
10104 (match_operand:DF 2 "register_operand" "0,f")))]
10105 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10106 "@
10107 mov%T3.d\\t%0,%1,%4
10108 mov%t3.d\\t%0,%2,%4"
10109 [(set_attr "type" "move")
10110 (set_attr "mode" "DF")])
10111
10112 ;; These are the main define_expand's used to make conditional moves.
10113
10114 (define_expand "movsicc"
10115 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10116 (set (match_operand:SI 0 "register_operand" "")
10117 (if_then_else:SI (match_dup 5)
10118 (match_operand:SI 2 "reg_or_0_operand" "")
10119 (match_operand:SI 3 "reg_or_0_operand" "")))]
10120 "mips_isa >= 4"
10121 "
10122 {
10123 gen_conditional_move (operands);
10124 DONE;
10125 }")
10126
10127 (define_expand "movdicc"
10128 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10129 (set (match_operand:DI 0 "register_operand" "")
10130 (if_then_else:DI (match_dup 5)
10131 (match_operand:DI 2 "se_reg_or_0_operand" "")
10132 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10133 "mips_isa >= 4"
10134 "
10135 {
10136 gen_conditional_move (operands);
10137 DONE;
10138 }")
10139
10140 (define_expand "movsfcc"
10141 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10142 (set (match_operand:SF 0 "register_operand" "")
10143 (if_then_else:SF (match_dup 5)
10144 (match_operand:SF 2 "register_operand" "")
10145 (match_operand:SF 3 "register_operand" "")))]
10146 "mips_isa >= 4 && TARGET_HARD_FLOAT"
10147 "
10148 {
10149 gen_conditional_move (operands);
10150 DONE;
10151 }")
10152
10153 (define_expand "movdfcc"
10154 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10155 (set (match_operand:DF 0 "register_operand" "")
10156 (if_then_else:DF (match_dup 5)
10157 (match_operand:DF 2 "register_operand" "")
10158 (match_operand:DF 3 "register_operand" "")))]
10159 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10160 "
10161 {
10162 gen_conditional_move (operands);
10163 DONE;
10164 }")
10165 \f
10166 ;;
10167 ;; ....................
10168 ;;
10169 ;; mips16 inline constant tables
10170 ;;
10171 ;; ....................
10172 ;;
10173
10174 (define_insn "consttable_qi"
10175 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
10176 "TARGET_MIPS16"
10177 "*
10178 {
10179 assemble_integer (operands[0], 1, 1);
10180 return \"\";
10181 }"
10182 [(set_attr "type" "unknown")
10183 (set_attr "mode" "QI")
10184 (set_attr "length" "8")])
10185
10186 (define_insn "consttable_hi"
10187 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
10188 "TARGET_MIPS16"
10189 "*
10190 {
10191 assemble_integer (operands[0], 2, 1);
10192 return \"\";
10193 }"
10194 [(set_attr "type" "unknown")
10195 (set_attr "mode" "HI")
10196 (set_attr "length" "8")])
10197
10198 (define_insn "consttable_si"
10199 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
10200 "TARGET_MIPS16"
10201 "*
10202 {
10203 assemble_integer (operands[0], 4, 1);
10204 return \"\";
10205 }"
10206 [(set_attr "type" "unknown")
10207 (set_attr "mode" "SI")
10208 (set_attr "length" "8")])
10209
10210 (define_insn "consttable_di"
10211 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
10212 "TARGET_MIPS16"
10213 "*
10214 {
10215 assemble_integer (operands[0], 8, 1);
10216 return \"\";
10217 }"
10218 [(set_attr "type" "unknown")
10219 (set_attr "mode" "DI")
10220 (set_attr "length" "16")])
10221
10222 (define_insn "consttable_sf"
10223 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
10224 "TARGET_MIPS16"
10225 "*
10226 {
10227 union real_extract u;
10228
10229 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10230 abort ();
10231 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
10232 assemble_real (u.d, SFmode);
10233 return \"\";
10234 }"
10235 [(set_attr "type" "unknown")
10236 (set_attr "mode" "SF")
10237 (set_attr "length" "8")])
10238
10239 (define_insn "consttable_df"
10240 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
10241 "TARGET_MIPS16"
10242 "*
10243 {
10244 union real_extract u;
10245
10246 if (GET_CODE (operands[0]) != CONST_DOUBLE)
10247 abort ();
10248 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
10249 assemble_real (u.d, DFmode);
10250 return \"\";
10251 }"
10252 [(set_attr "type" "unknown")
10253 (set_attr "mode" "DF")
10254 (set_attr "length" "16")])
10255
10256 (define_insn "align_2"
10257 [(unspec_volatile [(const_int 0)] 16)]
10258 "TARGET_MIPS16"
10259 ".align 1"
10260 [(set_attr "type" "unknown")
10261 (set_attr "mode" "HI")
10262 (set_attr "length" "8")])
10263
10264 (define_insn "align_4"
10265 [(unspec_volatile [(const_int 0)] 17)]
10266 "TARGET_MIPS16"
10267 ".align 2"
10268 [(set_attr "type" "unknown")
10269 (set_attr "mode" "SI")
10270 (set_attr "length" "8")])
10271
10272 (define_insn "align_8"
10273 [(unspec_volatile [(const_int 0)] 18)]
10274 "TARGET_MIPS16"
10275 ".align 3"
10276 [(set_attr "type" "unknown")
10277 (set_attr "mode" "DI")
10278 (set_attr "length" "12")])
10279 \f
10280 ;;
10281 ;; ....................
10282 ;;
10283 ;; mips16 peepholes
10284 ;;
10285 ;; ....................
10286 ;;
10287
10288 ;; On the mips16, reload will sometimes decide that a pseudo register
10289 ;; should go into $24, and then later on have to reload that register.
10290 ;; When that happens, we get a load of a general register followed by
10291 ;; a move from the general register to $24 followed by a branch.
10292 ;; These peepholes catch the common case, and fix it to just use the
10293 ;; general register for the branch.
10294
10295 (define_peephole
10296 [(set (match_operand:SI 0 "register_operand" "=t")
10297 (match_operand:SI 1 "register_operand" "d"))
10298 (set (pc)
10299 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10300 (const_int 0)])
10301 (match_operand 3 "pc_or_label_operand" "")
10302 (match_operand 4 "pc_or_label_operand" "")))]
10303 "TARGET_MIPS16
10304 && GET_CODE (operands[0]) == REG
10305 && REGNO (operands[0]) == 24
10306 && dead_or_set_p (insn, operands[0])
10307 && GET_CODE (operands[1]) == REG
10308 && M16_REG_P (REGNO (operands[1]))"
10309 "*
10310 {
10311 if (operands[3] != pc_rtx)
10312 return \"%*b%C2z\\t%1,%3\";
10313 else
10314 return \"%*b%N2z\\t%1,%4\";
10315 }"
10316 [(set_attr "type" "branch")
10317 (set_attr "mode" "none")
10318 (set_attr "length" "8")])
10319
10320 (define_peephole
10321 [(set (match_operand:DI 0 "register_operand" "=t")
10322 (match_operand:DI 1 "register_operand" "d"))
10323 (set (pc)
10324 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10325 (const_int 0)])
10326 (match_operand 3 "pc_or_label_operand" "")
10327 (match_operand 4 "pc_or_label_operand" "")))]
10328 "TARGET_MIPS16 && TARGET_64BIT
10329 && GET_CODE (operands[0]) == REG
10330 && REGNO (operands[0]) == 24
10331 && dead_or_set_p (insn, operands[0])
10332 && GET_CODE (operands[1]) == REG
10333 && M16_REG_P (REGNO (operands[1]))"
10334 "*
10335 {
10336 if (operands[3] != pc_rtx)
10337 return \"%*b%C2z\\t%1,%3\";
10338 else
10339 return \"%*b%N2z\\t%1,%4\";
10340 }"
10341 [(set_attr "type" "branch")
10342 (set_attr "mode" "none")
10343 (set_attr "length" "8")])
10344
10345 ;; We can also have the reverse reload: reload will spill $24 into
10346 ;; another register, and then do a branch on that register when it
10347 ;; could have just stuck with $24.
10348
10349 (define_peephole
10350 [(set (match_operand:SI 0 "register_operand" "=d")
10351 (match_operand:SI 1 "register_operand" "t"))
10352 (set (pc)
10353 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10354 (const_int 0)])
10355 (match_operand 3 "pc_or_label_operand" "")
10356 (match_operand 4 "pc_or_label_operand" "")))]
10357 "TARGET_MIPS16
10358 && GET_CODE (operands[1]) == REG
10359 && REGNO (operands[1]) == 24
10360 && GET_CODE (operands[0]) == REG
10361 && M16_REG_P (REGNO (operands[0]))
10362 && dead_or_set_p (insn, operands[0])"
10363 "*
10364 {
10365 if (operands[3] != pc_rtx)
10366 return \"%*bt%C2z\\t%3\";
10367 else
10368 return \"%*bt%N2z\\t%4\";
10369 }"
10370 [(set_attr "type" "branch")
10371 (set_attr "mode" "none")
10372 (set_attr "length" "8")])
10373
10374 (define_peephole
10375 [(set (match_operand:DI 0 "register_operand" "=d")
10376 (match_operand:DI 1 "register_operand" "t"))
10377 (set (pc)
10378 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10379 (const_int 0)])
10380 (match_operand 3 "pc_or_label_operand" "")
10381 (match_operand 4 "pc_or_label_operand" "")))]
10382 "TARGET_MIPS16 && TARGET_64BIT
10383 && GET_CODE (operands[1]) == REG
10384 && REGNO (operands[1]) == 24
10385 && GET_CODE (operands[0]) == REG
10386 && M16_REG_P (REGNO (operands[0]))
10387 && dead_or_set_p (insn, operands[0])"
10388 "*
10389 {
10390 if (operands[3] != pc_rtx)
10391 return \"%*bt%C2z\\t%3\";
10392 else
10393 return \"%*bt%N2z\\t%4\";
10394 }"
10395 [(set_attr "type" "branch")
10396 (set_attr "mode" "none")
10397 (set_attr "length" "8")])
10398
10399 ;; For the rare case where we need to load an address into a register
10400 ;; that can not be recognized by the normal movsi/addsi instructions.
10401 ;; I have no idea how many insns this can actually generate. It should
10402 ;; be rare, so over-estimating as 10 instructions should not have any
10403 ;; real performance impact.
10404 (define_insn "leasi"
10405 [(set (match_operand:SI 0 "register_operand" "=d")
10406 (match_operand:SI 1 "address_operand" "p"))]
10407 "Pmode == SImode"
10408 "la %0,%a1"
10409 [(set_attr "type" "arith")
10410 (set_attr "mode" "SI")
10411 (set_attr "length" "40")])
10412
10413 ;; Similarly for targets where we have 64bit pointers.
10414 (define_insn "leadi"
10415 [(set (match_operand:DI 0 "register_operand" "=d")
10416 (match_operand:DI 1 "address_operand" "p"))]
10417 "Pmode == DImode"
10418 "la %0,%a1"
10419 [(set_attr "type" "arith")
10420 (set_attr "mode" "DI")
10421 (set_attr "length" "40")])