]> gcc.gnu.org Git - gcc.git/blob - gcc/config/mips/mips.md
rtlanal.c (dead_or_set_regno_p): Ignore REG_DEAD notes after reload completes.
[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-97, 1998 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 ;; # instructions (4 bytes each)
70 (define_attr "length" "" (const_int 1))
71
72 ;; whether or not an instruction has a mandatory delay slot
73 (define_attr "dslot" "no,yes"
74 (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
75 (and (eq_attr "type" "load")
76 (and (eq (symbol_ref "mips_isa") (const_int 1))
77 (eq (symbol_ref "mips16") (const_int 0)))))
78 (const_string "yes")
79 (const_string "no")))
80
81 ;; Attribute describing the processor. This attribute must match exactly
82 ;; with the processor_type enumeration in mips.h.
83
84 ;; Attribute describing the processor
85 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
86 ;; (const
87 ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
88 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
89 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
90 ;; (const_string "default"))))
91
92 ;; ??? Fix everything that tests this attribute.
93 (define_attr "cpu"
94 "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
95 (const (symbol_ref "mips_cpu_attr")))
96
97 ;; Attribute defining whether or not we can use the branch-likely instructions
98
99 (define_attr "branch_likely" "no,yes"
100 (const
101 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
102 (const_string "yes")
103 (const_string "no"))))
104
105
106 ;; Describe a user's asm statement.
107 (define_asm_attributes
108 [(set_attr "type" "multi")])
109
110 ;; whether or not generating calls to position independent functions
111 (define_attr "abicalls" "no,yes"
112 (const (symbol_ref "mips_abicalls_attr")))
113
114 \f
115
116 ;; .........................
117 ;;
118 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
119 ;;
120 ;; .........................
121
122 (define_delay (and (eq_attr "type" "branch")
123 (eq (symbol_ref "mips16") (const_int 0)))
124 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
125 (nil)
126 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
127
128 (define_delay (eq_attr "type" "jump")
129 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
130 (nil)
131 (nil)])
132
133 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
134 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
135 (nil)
136 (nil)])
137
138 \f
139
140 ;; .........................
141 ;;
142 ;; Functional units
143 ;;
144 ;; .........................
145
146 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
147 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
148
149 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
150
151 (define_function_unit "memory" 1 0
152 (and (eq_attr "type" "load")
153 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
154 3 0)
155
156 (define_function_unit "memory" 1 0
157 (and (eq_attr "type" "load")
158 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
159 2 0)
160
161 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
162
163 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
164
165 (define_function_unit "imuldiv" 1 0
166 (eq_attr "type" "hilo")
167 1 3)
168
169 (define_function_unit "imuldiv" 1 0
170 (and (eq_attr "type" "imul")
171 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
172 17 17)
173
174 ;; On them mips16, we want to stronly discourage a mult from appearing
175 ;; after an mflo, since that requires explicit nop instructions. We
176 ;; do this by pretending that mflo ties up the function unit for long
177 ;; enough that the scheduler will ignore load stalls and the like when
178 ;; selecting instructions to between the two instructions.
179
180 (define_function_unit "imuldiv" 1 0
181 (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
182 1 5)
183
184 (define_function_unit "imuldiv" 1 0
185 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
186 12 12)
187
188 (define_function_unit "imuldiv" 1 0
189 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
190 10 10)
191
192 (define_function_unit "imuldiv" 1 0
193 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
194 4 4)
195
196 (define_function_unit "imuldiv" 1 0
197 (and (eq_attr "type" "imul")
198 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
199 1 1)
200
201 (define_function_unit "imuldiv" 1 0
202 (and (eq_attr "type" "imul")
203 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
204 4 4)
205
206 (define_function_unit "imuldiv" 1 0
207 (and (eq_attr "type" "imul")
208 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
209 5 5)
210
211 (define_function_unit "imuldiv" 1 0
212 (and (eq_attr "type" "imul")
213 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
214 8 8)
215
216 (define_function_unit "imuldiv" 1 0
217 (and (eq_attr "type" "imul")
218 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
219 9 9)
220
221 (define_function_unit "imuldiv" 1 0
222 (and (eq_attr "type" "idiv")
223 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
224 38 38)
225
226 (define_function_unit "imuldiv" 1 0
227 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
228 35 35)
229
230 (define_function_unit "imuldiv" 1 0
231 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
232 42 42)
233
234 (define_function_unit "imuldiv" 1 0
235 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
236 36 36)
237
238 (define_function_unit "imuldiv" 1 0
239 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
240 69 69)
241
242 (define_function_unit "imuldiv" 1 0
243 (and (eq_attr "type" "idiv")
244 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
245 35 35)
246
247 (define_function_unit "imuldiv" 1 0
248 (and (eq_attr "type" "idiv")
249 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
250 67 67)
251
252 (define_function_unit "imuldiv" 1 0
253 (and (eq_attr "type" "idiv")
254 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
255 37 37)
256
257 (define_function_unit "imuldiv" 1 0
258 (and (eq_attr "type" "idiv")
259 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
260 69 69)
261
262 (define_function_unit "imuldiv" 1 0
263 (and (eq_attr "type" "idiv")
264 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
265 36 36)
266
267 (define_function_unit "imuldiv" 1 0
268 (and (eq_attr "type" "idiv")
269 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
270 68 68)
271
272 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
273 ;; the FP hardware is part of the normal ALU circuitry. This means FP
274 ;; instructions affect the pipe-line, and no functional unit
275 ;; parallelism can occur on R4300 processors. To force GCC into coding
276 ;; for only a single functional unit, we force the R4300 FP
277 ;; instructions to be processed in the "imuldiv" unit.
278
279 (define_function_unit "adder" 1 1
280 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
281 3 0)
282
283 (define_function_unit "adder" 1 1
284 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
285 2 0)
286
287 (define_function_unit "adder" 1 1
288 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
289 1 0)
290
291 (define_function_unit "adder" 1 1
292 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
293 4 0)
294
295 (define_function_unit "adder" 1 1
296 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
297 2 0)
298
299 (define_function_unit "adder" 1 1
300 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
301 3 0)
302
303 (define_function_unit "adder" 1 1
304 (and (eq_attr "type" "fabs,fneg")
305 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
306 2 0)
307
308 (define_function_unit "adder" 1 1
309 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
310 1 0)
311
312 (define_function_unit "mult" 1 1
313 (and (eq_attr "type" "fmul")
314 (and (eq_attr "mode" "SF")
315 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
316 7 0)
317
318 (define_function_unit "mult" 1 1
319 (and (eq_attr "type" "fmul")
320 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
321 4 0)
322
323 (define_function_unit "mult" 1 1
324 (and (eq_attr "type" "fmul")
325 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
326 5 0)
327
328 (define_function_unit "mult" 1 1
329 (and (eq_attr "type" "fmul")
330 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
331 8 0)
332
333 (define_function_unit "mult" 1 1
334 (and (eq_attr "type" "fmul")
335 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
336 8 0)
337
338 (define_function_unit "mult" 1 1
339 (and (eq_attr "type" "fmul")
340 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
341 5 0)
342
343 (define_function_unit "mult" 1 1
344 (and (eq_attr "type" "fmul")
345 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
346 6 0)
347
348 (define_function_unit "divide" 1 1
349 (and (eq_attr "type" "fdiv")
350 (and (eq_attr "mode" "SF")
351 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
352 23 0)
353
354 (define_function_unit "divide" 1 1
355 (and (eq_attr "type" "fdiv")
356 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
357 12 0)
358
359 (define_function_unit "divide" 1 1
360 (and (eq_attr "type" "fdiv")
361 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
362 15 0)
363
364 (define_function_unit "divide" 1 1
365 (and (eq_attr "type" "fdiv")
366 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
367 32 0)
368
369 (define_function_unit "divide" 1 1
370 (and (eq_attr "type" "fdiv")
371 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
372 21 0)
373
374 (define_function_unit "divide" 1 1
375 (and (eq_attr "type" "fdiv")
376 (and (eq_attr "mode" "DF")
377 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
378 36 0)
379
380 (define_function_unit "divide" 1 1
381 (and (eq_attr "type" "fdiv")
382 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
383 19 0)
384
385 (define_function_unit "divide" 1 1
386 (and (eq_attr "type" "fdiv")
387 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
388 16 0)
389
390 (define_function_unit "divide" 1 1
391 (and (eq_attr "type" "fdiv")
392 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
393 61 0)
394
395 ;;; ??? Is this number right?
396 (define_function_unit "divide" 1 1
397 (and (eq_attr "type" "fsqrt")
398 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
399 54 0)
400
401 (define_function_unit "divide" 1 1
402 (and (eq_attr "type" "fsqrt")
403 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
404 31 0)
405
406 (define_function_unit "divide" 1 1
407 (and (eq_attr "type" "fsqrt")
408 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
409 21 0)
410
411 ;;; ??? Is this number right?
412 (define_function_unit "divide" 1 1
413 (and (eq_attr "type" "fsqrt")
414 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
415 112 0)
416
417 (define_function_unit "divide" 1 1
418 (and (eq_attr "type" "fsqrt")
419 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
420 60 0)
421
422 (define_function_unit "divide" 1 1
423 (and (eq_attr "type" "fsqrt")
424 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
425 36 0)
426
427 ;; R4300 FP instruction classes treated as part of the "imuldiv"
428 ;; functional unit:
429
430 (define_function_unit "imuldiv" 1 0
431 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
432 3 3)
433
434 (define_function_unit "imuldiv" 1 0
435 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
436 1 1)
437
438 (define_function_unit "imuldiv" 1 0
439 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
440 5 5)
441 (define_function_unit "imuldiv" 1 0
442 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
443 8 8)
444
445 (define_function_unit "imuldiv" 1 0
446 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
447 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
448 29 29)
449 (define_function_unit "imuldiv" 1 0
450 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
451 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
452 58 58)
453 \f
454 ;; The following functional units do not use the cpu type, and use
455 ;; much less memory in genattrtab.c.
456
457 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
458 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
459 ;;
460 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
461 ;;
462 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
463 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
464 ;;
465 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
466 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
467 ;;
468 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
469 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
470 ;;
471 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
472 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
473 ;;
474 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
475 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
476 ;;
477 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
478 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
479
480 \f
481 ;;
482 ;; ....................
483 ;;
484 ;; ADDITION
485 ;;
486 ;; ....................
487 ;;
488
489 (define_insn "adddf3"
490 [(set (match_operand:DF 0 "register_operand" "=f")
491 (plus:DF (match_operand:DF 1 "register_operand" "f")
492 (match_operand:DF 2 "register_operand" "f")))]
493 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
494 "add.d\\t%0,%1,%2"
495 [(set_attr "type" "fadd")
496 (set_attr "mode" "DF")
497 (set_attr "length" "1")])
498
499 (define_insn "addsf3"
500 [(set (match_operand:SF 0 "register_operand" "=f")
501 (plus:SF (match_operand:SF 1 "register_operand" "f")
502 (match_operand:SF 2 "register_operand" "f")))]
503 "TARGET_HARD_FLOAT"
504 "add.s\\t%0,%1,%2"
505 [(set_attr "type" "fadd")
506 (set_attr "mode" "SF")
507 (set_attr "length" "1")])
508
509 (define_expand "addsi3"
510 [(set (match_operand:SI 0 "register_operand" "=d")
511 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
512 (match_operand:SI 2 "arith_operand" "dI")))]
513 ""
514 "
515 {
516 /* The mips16 assembler handles -32768 correctly, and so does gas,
517 but some other MIPS assemblers think that -32768 needs to be
518 loaded into a register before it can be added in. */
519 if (! TARGET_MIPS16
520 && ! TARGET_GAS
521 && GET_CODE (operands[2]) == CONST_INT
522 && INTVAL (operands[2]) == -32768)
523 operands[2] = force_reg (SImode, operands[2]);
524 }")
525
526 (define_insn "addsi3_internal"
527 [(set (match_operand:SI 0 "register_operand" "=d")
528 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
529 (match_operand:SI 2 "arith_operand" "dI")))]
530 "! TARGET_MIPS16
531 && (TARGET_GAS
532 || GET_CODE (operands[2]) != CONST_INT
533 || INTVAL (operands[2]) != -32768)"
534 "addu\\t%0,%z1,%2"
535 [(set_attr "type" "arith")
536 (set_attr "mode" "SI")
537 (set_attr "length" "1")])
538
539 ;; For the mips16, we need to recognize stack pointer additions
540 ;; explicitly, since we don't have a constraint for $sp. These insns
541 ;; will be generated by the save_restore_insns functions.
542
543 (define_insn ""
544 [(set (reg:SI 29)
545 (plus:SI (reg:SI 29)
546 (match_operand:SI 0 "small_int" "I")))]
547 "TARGET_MIPS16"
548 "addu\\t%$,%$,%0"
549 [(set_attr "type" "arith")
550 (set_attr "mode" "SI")
551 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
552 (const_int 1)
553 (const_int 2)))])
554
555 (define_insn ""
556 [(set (match_operand:SI 0 "register_operand" "=d")
557 (plus:SI (reg:SI 29)
558 (match_operand:SI 1 "small_int" "I")))]
559 "TARGET_MIPS16"
560 "addu\\t%0,%$,%1"
561 [(set_attr "type" "arith")
562 (set_attr "mode" "SI")
563 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
564 (const_int 1)
565 (const_int 2)))])
566
567 (define_insn ""
568 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
569 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
570 (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
571 "TARGET_MIPS16
572 && (GET_CODE (operands[1]) != REG
573 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
574 || M16_REG_P (REGNO (operands[1]))
575 || REGNO (operands[1]) == ARG_POINTER_REGNUM
576 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
577 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
578 && (GET_CODE (operands[2]) != REG
579 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
580 || M16_REG_P (REGNO (operands[2]))
581 || REGNO (operands[2]) == ARG_POINTER_REGNUM
582 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
583 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
584 "*
585 {
586 if (REGNO (operands[0]) == REGNO (operands[1]))
587 return \"addu\\t%0,%2\";
588 return \"addu\\t%0,%1,%2\";
589 }"
590 [(set_attr "type" "arith")
591 (set_attr "mode" "SI")
592 (set_attr_alternative "length"
593 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
594 (const_int 1)
595 (const_int 2))
596 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
597 (const_int 1)
598 (const_int 2))
599 (const_int 1)])])
600
601
602 ;; On the mips16, we can sometimes split an add of a constant which is
603 ;; a 4 byte instruction into two adds which are both 2 byte
604 ;; instructions. There are two cases: one where we are adding a
605 ;; constant plus a register to another register, and one where we are
606 ;; simply adding a constant to a register.
607
608 (define_split
609 [(set (match_operand:SI 0 "register_operand" "")
610 (plus:SI (match_dup 0)
611 (match_operand:SI 1 "const_int_operand" "")))]
612 "TARGET_MIPS16 && reload_completed
613 && GET_CODE (operands[0]) == REG
614 && M16_REG_P (REGNO (operands[0]))
615 && GET_CODE (operands[1]) == CONST_INT
616 && ((INTVAL (operands[1]) > 0x7f
617 && INTVAL (operands[1]) <= 0x7f + 0x7f)
618 || (INTVAL (operands[1]) < - 0x80
619 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
620 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
621 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
622 "
623 {
624 HOST_WIDE_INT val = INTVAL (operands[1]);
625
626 if (val >= 0)
627 {
628 operands[1] = GEN_INT (0x7f);
629 operands[2] = GEN_INT (val - 0x7f);
630 }
631 else
632 {
633 operands[1] = GEN_INT (- 0x80);
634 operands[2] = GEN_INT (val + 0x80);
635 }
636 }")
637
638 (define_split
639 [(set (match_operand:SI 0 "register_operand" "")
640 (plus:SI (match_operand:SI 1 "register_operand" "")
641 (match_operand:SI 2 "const_int_operand" "")))]
642 "TARGET_MIPS16 && reload_completed
643 && GET_CODE (operands[0]) == REG
644 && M16_REG_P (REGNO (operands[0]))
645 && GET_CODE (operands[1]) == REG
646 && M16_REG_P (REGNO (operands[1]))
647 && REGNO (operands[0]) != REGNO (operands[1])
648 && GET_CODE (operands[2]) == CONST_INT
649 && ((INTVAL (operands[2]) > 0x7
650 && INTVAL (operands[2]) <= 0x7 + 0x7f)
651 || (INTVAL (operands[2]) < - 0x8
652 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
653 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
654 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
655 "
656 {
657 HOST_WIDE_INT val = INTVAL (operands[2]);
658
659 if (val >= 0)
660 {
661 operands[2] = GEN_INT (0x7);
662 operands[3] = GEN_INT (val - 0x7);
663 }
664 else
665 {
666 operands[2] = GEN_INT (- 0x8);
667 operands[3] = GEN_INT (val + 0x8);
668 }
669 }")
670
671 (define_expand "adddi3"
672 [(parallel [(set (match_operand:DI 0 "register_operand" "")
673 (plus:DI (match_operand:DI 1 "se_register_operand" "")
674 (match_operand:DI 2 "se_arith_operand" "")))
675 (clobber (match_dup 3))])]
676 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
677 "
678 {
679 /* The mips16 assembler handles -32768 correctly, and so does gas,
680 but some other MIPS assemblers think that -32768 needs to be
681 loaded into a register before it can be added in. */
682 if (! TARGET_MIPS16
683 && ! TARGET_GAS
684 && GET_CODE (operands[2]) == CONST_INT
685 && INTVAL (operands[2]) == -32768)
686 operands[2] = force_reg (DImode, operands[2]);
687
688 if (TARGET_64BIT)
689 {
690 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
691 operands[2]));
692 DONE;
693 }
694
695 operands[3] = gen_reg_rtx (SImode);
696 }")
697
698 (define_insn "adddi3_internal_1"
699 [(set (match_operand:DI 0 "register_operand" "=d,&d")
700 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
701 (match_operand:DI 2 "register_operand" "d,d")))
702 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
703 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
704 "*
705 {
706 return (REGNO (operands[0]) == REGNO (operands[1])
707 && REGNO (operands[0]) == REGNO (operands[2]))
708 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
709 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
710 }"
711 [(set_attr "type" "darith")
712 (set_attr "mode" "DI")
713 (set_attr "length" "4")])
714
715 (define_split
716 [(set (match_operand:DI 0 "register_operand" "")
717 (plus:DI (match_operand:DI 1 "register_operand" "")
718 (match_operand:DI 2 "register_operand" "")))
719 (clobber (match_operand:SI 3 "register_operand" ""))]
720 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
721 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
722 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
723 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
724 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
725 && (REGNO (operands[0]) != REGNO (operands[1])
726 || REGNO (operands[0]) != REGNO (operands[2]))"
727
728 [(set (subreg:SI (match_dup 0) 0)
729 (plus:SI (subreg:SI (match_dup 1) 0)
730 (subreg:SI (match_dup 2) 0)))
731
732 (set (match_dup 3)
733 (ltu:SI (subreg:SI (match_dup 0) 0)
734 (subreg:SI (match_dup 2) 0)))
735
736 (set (subreg:SI (match_dup 0) 1)
737 (plus:SI (subreg:SI (match_dup 1) 1)
738 (subreg:SI (match_dup 2) 1)))
739
740 (set (subreg:SI (match_dup 0) 1)
741 (plus:SI (subreg:SI (match_dup 0) 1)
742 (match_dup 3)))]
743 "")
744
745 (define_split
746 [(set (match_operand:DI 0 "register_operand" "")
747 (plus:DI (match_operand:DI 1 "register_operand" "")
748 (match_operand:DI 2 "register_operand" "")))
749 (clobber (match_operand:SI 3 "register_operand" ""))]
750 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
751 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
752 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
753 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
754 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
755 && (REGNO (operands[0]) != REGNO (operands[1])
756 || REGNO (operands[0]) != REGNO (operands[2]))"
757
758 [(set (subreg:SI (match_dup 0) 1)
759 (plus:SI (subreg:SI (match_dup 1) 1)
760 (subreg:SI (match_dup 2) 1)))
761
762 (set (match_dup 3)
763 (ltu:SI (subreg:SI (match_dup 0) 1)
764 (subreg:SI (match_dup 2) 1)))
765
766 (set (subreg:SI (match_dup 0) 0)
767 (plus:SI (subreg:SI (match_dup 1) 0)
768 (subreg:SI (match_dup 2) 0)))
769
770 (set (subreg:SI (match_dup 0) 0)
771 (plus:SI (subreg:SI (match_dup 0) 0)
772 (match_dup 3)))]
773 "")
774
775 (define_insn "adddi3_internal_2"
776 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
777 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
778 (match_operand:DI 2 "small_int" "P,J,N")))
779 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
780 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
781 && INTVAL (operands[2]) != -32768"
782 "@
783 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
784 move\\t%L0,%L1\;move\\t%M0,%M1
785 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
786 [(set_attr "type" "darith")
787 (set_attr "mode" "DI")
788 (set_attr "length" "3,2,4")])
789
790 (define_split
791 [(set (match_operand:DI 0 "register_operand" "")
792 (plus:DI (match_operand:DI 1 "register_operand" "")
793 (match_operand:DI 2 "small_int" "")))
794 (clobber (match_operand:SI 3 "register_operand" "=d"))]
795 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
796 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
797 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
798 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
799 && INTVAL (operands[2]) > 0"
800
801 [(set (subreg:SI (match_dup 0) 0)
802 (plus:SI (subreg:SI (match_dup 1) 0)
803 (match_dup 2)))
804
805 (set (match_dup 3)
806 (ltu:SI (subreg:SI (match_dup 0) 0)
807 (match_dup 2)))
808
809 (set (subreg:SI (match_dup 0) 1)
810 (plus:SI (subreg:SI (match_dup 1) 1)
811 (match_dup 3)))]
812 "")
813
814 (define_split
815 [(set (match_operand:DI 0 "register_operand" "")
816 (plus:DI (match_operand:DI 1 "register_operand" "")
817 (match_operand:DI 2 "small_int" "")))
818 (clobber (match_operand:SI 3 "register_operand" "=d"))]
819 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
820 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
821 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
822 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
823 && INTVAL (operands[2]) > 0"
824
825 [(set (subreg:SI (match_dup 0) 1)
826 (plus:SI (subreg:SI (match_dup 1) 1)
827 (match_dup 2)))
828
829 (set (match_dup 3)
830 (ltu:SI (subreg:SI (match_dup 0) 1)
831 (match_dup 2)))
832
833 (set (subreg:SI (match_dup 0) 0)
834 (plus:SI (subreg:SI (match_dup 1) 0)
835 (match_dup 3)))]
836 "")
837
838 (define_insn "adddi3_internal_3"
839 [(set (match_operand:DI 0 "register_operand" "=d")
840 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
841 (match_operand:DI 2 "se_arith_operand" "dI")))]
842 "TARGET_64BIT
843 && !TARGET_MIPS16
844 && (TARGET_GAS
845 || GET_CODE (operands[2]) != CONST_INT
846 || INTVAL (operands[2]) != -32768)"
847 "*
848 {
849 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
850 ? \"dsubu\\t%0,%z1,%n2\"
851 : \"daddu\\t%0,%z1,%2\";
852 }"
853 [(set_attr "type" "darith")
854 (set_attr "mode" "DI")
855 (set_attr "length" "1")])
856
857 ;; For the mips16, we need to recognize stack pointer additions
858 ;; explicitly, since we don't have a constraint for $sp. These insns
859 ;; will be generated by the save_restore_insns functions.
860
861 (define_insn ""
862 [(set (reg:DI 29)
863 (plus:DI (reg:DI 29)
864 (match_operand:DI 0 "small_int" "I")))]
865 "TARGET_MIPS16 && TARGET_64BIT"
866 "daddu\\t%$,%$,%0"
867 [(set_attr "type" "arith")
868 (set_attr "mode" "DI")
869 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
870 (const_int 1)
871 (const_int 2)))])
872
873 (define_insn ""
874 [(set (match_operand:DI 0 "register_operand" "=d")
875 (plus:DI (reg:DI 29)
876 (match_operand:DI 1 "small_int" "I")))]
877 "TARGET_MIPS16 && TARGET_64BIT"
878 "daddu\\t%0,%$,%1"
879 [(set_attr "type" "arith")
880 (set_attr "mode" "DI")
881 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
882 (const_int 1)
883 (const_int 2)))])
884
885 (define_insn ""
886 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
887 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
888 (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
889 "TARGET_MIPS16 && TARGET_64BIT
890 && (GET_CODE (operands[1]) != REG
891 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
892 || M16_REG_P (REGNO (operands[1]))
893 || REGNO (operands[1]) == ARG_POINTER_REGNUM
894 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
895 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
896 && (GET_CODE (operands[2]) != REG
897 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
898 || M16_REG_P (REGNO (operands[2]))
899 || REGNO (operands[2]) == ARG_POINTER_REGNUM
900 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
901 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
902 "*
903 {
904 if (REGNO (operands[0]) == REGNO (operands[1]))
905 return \"daddu\\t%0,%2\";
906 return \"daddu\\t%0,%1,%2\";
907 }"
908 [(set_attr "type" "arith")
909 (set_attr "mode" "DI")
910 (set_attr_alternative "length"
911 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
912 (const_int 1)
913 (const_int 2))
914 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
915 (const_int 1)
916 (const_int 2))
917 (const_int 1)])])
918
919
920 ;; On the mips16, we can sometimes split an add of a constant which is
921 ;; a 4 byte instruction into two adds which are both 2 byte
922 ;; instructions. There are two cases: one where we are adding a
923 ;; constant plus a register to another register, and one where we are
924 ;; simply adding a constant to a register.
925
926 (define_split
927 [(set (match_operand:DI 0 "register_operand" "")
928 (plus:DI (match_dup 0)
929 (match_operand:DI 1 "const_int_operand" "")))]
930 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
931 && GET_CODE (operands[0]) == REG
932 && M16_REG_P (REGNO (operands[0]))
933 && GET_CODE (operands[1]) == CONST_INT
934 && ((INTVAL (operands[1]) > 0xf
935 && INTVAL (operands[1]) <= 0xf + 0xf)
936 || (INTVAL (operands[1]) < - 0x10
937 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
938 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
939 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
940 "
941 {
942 HOST_WIDE_INT val = INTVAL (operands[1]);
943
944 if (val >= 0)
945 {
946 operands[1] = GEN_INT (0xf);
947 operands[2] = GEN_INT (val - 0xf);
948 }
949 else
950 {
951 operands[1] = GEN_INT (- 0x10);
952 operands[2] = GEN_INT (val + 0x10);
953 }
954 }")
955
956 (define_split
957 [(set (match_operand:DI 0 "register_operand" "")
958 (plus:DI (match_operand:DI 1 "register_operand" "")
959 (match_operand:DI 2 "const_int_operand" "")))]
960 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
961 && GET_CODE (operands[0]) == REG
962 && M16_REG_P (REGNO (operands[0]))
963 && GET_CODE (operands[1]) == REG
964 && M16_REG_P (REGNO (operands[1]))
965 && REGNO (operands[0]) != REGNO (operands[1])
966 && GET_CODE (operands[2]) == CONST_INT
967 && ((INTVAL (operands[2]) > 0x7
968 && INTVAL (operands[2]) <= 0x7 + 0xf)
969 || (INTVAL (operands[2]) < - 0x8
970 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
971 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
972 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
973 "
974 {
975 HOST_WIDE_INT val = INTVAL (operands[2]);
976
977 if (val >= 0)
978 {
979 operands[2] = GEN_INT (0x7);
980 operands[3] = GEN_INT (val - 0x7);
981 }
982 else
983 {
984 operands[2] = GEN_INT (- 0x8);
985 operands[3] = GEN_INT (val + 0x8);
986 }
987 }")
988
989 (define_insn "addsi3_internal_2"
990 [(set (match_operand:DI 0 "register_operand" "=d")
991 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
992 (match_operand:SI 2 "arith_operand" "dI"))))]
993 "TARGET_64BIT
994 && !TARGET_MIPS16
995 && (TARGET_GAS
996 || GET_CODE (operands[2]) != CONST_INT
997 || INTVAL (operands[2]) != -32768)"
998 "*
999 {
1000 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1001 ? \"subu\\t%0,%z1,%n2\"
1002 : \"addu\\t%0,%z1,%2\";
1003 }"
1004 [(set_attr "type" "arith")
1005 (set_attr "mode" "SI")
1006 (set_attr "length" "1")])
1007
1008 (define_insn ""
1009 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1010 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1011 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1012 "TARGET_MIPS16 && TARGET_64BIT"
1013 "*
1014 {
1015 if (REGNO (operands[0]) == REGNO (operands[1]))
1016 return \"addu\\t%0,%2\";
1017 return \"addu\\t%0,%1,%2\";
1018 }"
1019 [(set_attr "type" "arith")
1020 (set_attr "mode" "SI")
1021 (set_attr_alternative "length"
1022 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1023 (const_int 1)
1024 (const_int 2))
1025 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1026 (const_int 1)
1027 (const_int 2))
1028 (const_int 1)])])
1029
1030 \f
1031 ;;
1032 ;; ....................
1033 ;;
1034 ;; SUBTRACTION
1035 ;;
1036 ;; ....................
1037 ;;
1038
1039 (define_insn "subdf3"
1040 [(set (match_operand:DF 0 "register_operand" "=f")
1041 (minus:DF (match_operand:DF 1 "register_operand" "f")
1042 (match_operand:DF 2 "register_operand" "f")))]
1043 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1044 "sub.d\\t%0,%1,%2"
1045 [(set_attr "type" "fadd")
1046 (set_attr "mode" "DF")
1047 (set_attr "length" "1")])
1048
1049 (define_insn "subsf3"
1050 [(set (match_operand:SF 0 "register_operand" "=f")
1051 (minus:SF (match_operand:SF 1 "register_operand" "f")
1052 (match_operand:SF 2 "register_operand" "f")))]
1053 "TARGET_HARD_FLOAT"
1054 "sub.s\\t%0,%1,%2"
1055 [(set_attr "type" "fadd")
1056 (set_attr "mode" "SF")
1057 (set_attr "length" "1")])
1058
1059 (define_expand "subsi3"
1060 [(set (match_operand:SI 0 "register_operand" "=d")
1061 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1062 (match_operand:SI 2 "arith_operand" "dI")))]
1063 ""
1064 "
1065 {
1066 if (GET_CODE (operands[2]) == CONST_INT
1067 && (INTVAL (operands[2]) == -32768
1068 || (TARGET_MIPS16
1069 && INTVAL (operands[2]) == -0x4000)))
1070 operands[2] = force_reg (SImode, operands[2]);
1071 }")
1072
1073 (define_insn "subsi3_internal"
1074 [(set (match_operand:SI 0 "register_operand" "=d")
1075 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1076 (match_operand:SI 2 "arith_operand" "dI")))]
1077 "!TARGET_MIPS16
1078 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1079 "subu\\t%0,%z1,%2"
1080 [(set_attr "type" "arith")
1081 (set_attr "mode" "SI")
1082 (set_attr "length" "1")])
1083
1084 ;; For the mips16, we need to recognize stack pointer subtractions
1085 ;; explicitly, since we don't have a constraint for $sp. These insns
1086 ;; will be generated by the save_restore_insns functions.
1087
1088 (define_insn ""
1089 [(set (reg:SI 29)
1090 (minus:SI (reg:SI 29)
1091 (match_operand:SI 0 "small_int" "I")))]
1092 "TARGET_MIPS16
1093 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1094 "addu\\t%$,%$,%n0"
1095 [(set_attr "type" "arith")
1096 (set_attr "mode" "SI")
1097 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1098 (const_int 1)
1099 (const_int 2)))])
1100
1101 (define_insn ""
1102 [(set (match_operand:SI 0 "register_operand" "=d")
1103 (minus:SI (reg:SI 29)
1104 (match_operand:SI 1 "small_int" "I")))]
1105 "TARGET_MIPS16
1106 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1107 "addu\\t%0,%$,%n1"
1108 [(set_attr "type" "arith")
1109 (set_attr "mode" "SI")
1110 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1111 (const_int 1)
1112 (const_int 2)))])
1113
1114
1115 (define_insn ""
1116 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1117 (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1118 (match_operand:SI 2 "arith_operand" "I,O,d")))]
1119 "TARGET_MIPS16
1120 && (GET_CODE (operands[2]) != CONST_INT
1121 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1122 "*
1123 {
1124 if (REGNO (operands[0]) == REGNO (operands[1]))
1125 return \"subu\\t%0,%2\";
1126 return \"subu\\t%0,%1,%2\";
1127 }"
1128 [(set_attr "type" "arith")
1129 (set_attr "mode" "SI")
1130 (set_attr_alternative "length"
1131 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1132 (const_int 1)
1133 (const_int 2))
1134 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1135 (const_int 1)
1136 (const_int 2))
1137 (const_int 1)])])
1138
1139 ;; On the mips16, we can sometimes split an subtract of a constant
1140 ;; which is a 4 byte instruction into two adds which are both 2 byte
1141 ;; instructions. There are two cases: one where we are setting a
1142 ;; register to a register minus a constant, and one where we are
1143 ;; simply subtracting a constant from a register.
1144
1145 (define_split
1146 [(set (match_operand:SI 0 "register_operand" "")
1147 (minus:SI (match_dup 0)
1148 (match_operand:SI 1 "const_int_operand" "")))]
1149 "TARGET_MIPS16 && reload_completed
1150 && GET_CODE (operands[0]) == REG
1151 && M16_REG_P (REGNO (operands[0]))
1152 && GET_CODE (operands[1]) == CONST_INT
1153 && ((INTVAL (operands[1]) > 0x80
1154 && INTVAL (operands[1]) <= 0x80 + 0x80)
1155 || (INTVAL (operands[1]) < - 0x7f
1156 && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1157 [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1158 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1159 "
1160 {
1161 HOST_WIDE_INT val = INTVAL (operands[1]);
1162
1163 if (val >= 0)
1164 {
1165 operands[1] = GEN_INT (0x80);
1166 operands[2] = GEN_INT (val - 0x80);
1167 }
1168 else
1169 {
1170 operands[1] = GEN_INT (- 0x7f);
1171 operands[2] = GEN_INT (val + 0x7f);
1172 }
1173 }")
1174
1175 (define_split
1176 [(set (match_operand:SI 0 "register_operand" "")
1177 (minus:SI (match_operand:SI 1 "register_operand" "")
1178 (match_operand:SI 2 "const_int_operand" "")))]
1179 "TARGET_MIPS16 && reload_completed
1180 && GET_CODE (operands[0]) == REG
1181 && M16_REG_P (REGNO (operands[0]))
1182 && GET_CODE (operands[1]) == REG
1183 && M16_REG_P (REGNO (operands[1]))
1184 && REGNO (operands[0]) != REGNO (operands[1])
1185 && GET_CODE (operands[2]) == CONST_INT
1186 && ((INTVAL (operands[2]) > 0x8
1187 && INTVAL (operands[2]) <= 0x8 + 0x80)
1188 || (INTVAL (operands[2]) < - 0x7
1189 && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1190 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1191 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1192 "
1193 {
1194 HOST_WIDE_INT val = INTVAL (operands[2]);
1195
1196 if (val >= 0)
1197 {
1198 operands[2] = GEN_INT (0x8);
1199 operands[3] = GEN_INT (val - 0x8);
1200 }
1201 else
1202 {
1203 operands[2] = GEN_INT (- 0x7);
1204 operands[3] = GEN_INT (val + 0x7);
1205 }
1206 }")
1207
1208 (define_expand "subdi3"
1209 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1210 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1211 (match_operand:DI 2 "se_register_operand" "d")))
1212 (clobber (match_dup 3))])]
1213 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1214 "
1215 {
1216 if (TARGET_64BIT)
1217 {
1218 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1219 operands[2]));
1220 DONE;
1221 }
1222
1223 operands[3] = gen_reg_rtx (SImode);
1224 }")
1225
1226 (define_insn "subdi3_internal"
1227 [(set (match_operand:DI 0 "register_operand" "=d")
1228 (minus:DI (match_operand:DI 1 "register_operand" "d")
1229 (match_operand:DI 2 "register_operand" "d")))
1230 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1231 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1232 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1233 [(set_attr "type" "darith")
1234 (set_attr "mode" "DI")
1235 (set_attr "length" "4")])
1236
1237 (define_split
1238 [(set (match_operand:DI 0 "register_operand" "")
1239 (minus:DI (match_operand:DI 1 "register_operand" "")
1240 (match_operand:DI 2 "register_operand" "")))
1241 (clobber (match_operand:SI 3 "register_operand" ""))]
1242 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1243 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1244 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1245 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1246 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1247
1248 [(set (match_dup 3)
1249 (ltu:SI (subreg:SI (match_dup 1) 0)
1250 (subreg:SI (match_dup 2) 0)))
1251
1252 (set (subreg:SI (match_dup 0) 0)
1253 (minus:SI (subreg:SI (match_dup 1) 0)
1254 (subreg:SI (match_dup 2) 0)))
1255
1256 (set (subreg:SI (match_dup 0) 1)
1257 (minus:SI (subreg:SI (match_dup 1) 1)
1258 (subreg:SI (match_dup 2) 1)))
1259
1260 (set (subreg:SI (match_dup 0) 1)
1261 (minus:SI (subreg:SI (match_dup 0) 1)
1262 (match_dup 3)))]
1263 "")
1264
1265 (define_split
1266 [(set (match_operand:DI 0 "register_operand" "")
1267 (minus:DI (match_operand:DI 1 "register_operand" "")
1268 (match_operand:DI 2 "register_operand" "")))
1269 (clobber (match_operand:SI 3 "register_operand" ""))]
1270 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1271 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1272 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1273 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1274 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1275
1276 [(set (match_dup 3)
1277 (ltu:SI (subreg:SI (match_dup 1) 1)
1278 (subreg:SI (match_dup 2) 1)))
1279
1280 (set (subreg:SI (match_dup 0) 1)
1281 (minus:SI (subreg:SI (match_dup 1) 1)
1282 (subreg:SI (match_dup 2) 1)))
1283
1284 (set (subreg:SI (match_dup 0) 0)
1285 (minus:SI (subreg:SI (match_dup 1) 0)
1286 (subreg:SI (match_dup 2) 0)))
1287
1288 (set (subreg:SI (match_dup 0) 0)
1289 (minus:SI (subreg:SI (match_dup 0) 0)
1290 (match_dup 3)))]
1291 "")
1292
1293 (define_insn "subdi3_internal_2"
1294 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1295 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1296 (match_operand:DI 2 "small_int" "P,J,N")))
1297 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1298 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1299 && INTVAL (operands[2]) != -32768"
1300 "@
1301 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1302 move\\t%L0,%L1\;move\\t%M0,%M1
1303 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1304 [(set_attr "type" "darith")
1305 (set_attr "mode" "DI")
1306 (set_attr "length" "3,2,4")])
1307
1308 (define_split
1309 [(set (match_operand:DI 0 "register_operand" "")
1310 (minus:DI (match_operand:DI 1 "register_operand" "")
1311 (match_operand:DI 2 "small_int" "")))
1312 (clobber (match_operand:SI 3 "register_operand" ""))]
1313 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1314 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1315 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1316 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1317 && INTVAL (operands[2]) > 0"
1318
1319 [(set (match_dup 3)
1320 (ltu:SI (subreg:SI (match_dup 1) 0)
1321 (match_dup 2)))
1322
1323 (set (subreg:SI (match_dup 0) 0)
1324 (minus:SI (subreg:SI (match_dup 1) 0)
1325 (match_dup 2)))
1326
1327 (set (subreg:SI (match_dup 0) 1)
1328 (minus:SI (subreg:SI (match_dup 1) 1)
1329 (match_dup 3)))]
1330 "")
1331
1332 (define_split
1333 [(set (match_operand:DI 0 "register_operand" "")
1334 (minus:DI (match_operand:DI 1 "register_operand" "")
1335 (match_operand:DI 2 "small_int" "")))
1336 (clobber (match_operand:SI 3 "register_operand" ""))]
1337 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1338 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1339 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1340 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1341 && INTVAL (operands[2]) > 0"
1342
1343 [(set (match_dup 3)
1344 (ltu:SI (subreg:SI (match_dup 1) 1)
1345 (match_dup 2)))
1346
1347 (set (subreg:SI (match_dup 0) 1)
1348 (minus:SI (subreg:SI (match_dup 1) 1)
1349 (match_dup 2)))
1350
1351 (set (subreg:SI (match_dup 0) 0)
1352 (minus:SI (subreg:SI (match_dup 1) 0)
1353 (match_dup 3)))]
1354 "")
1355
1356 (define_insn "subdi3_internal_3"
1357 [(set (match_operand:DI 0 "register_operand" "=d")
1358 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1359 (match_operand:DI 2 "se_arith_operand" "dI")))]
1360 "TARGET_64BIT && !TARGET_MIPS16
1361 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1362 "*
1363 {
1364 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1365 ? \"daddu\\t%0,%z1,%n2\"
1366 : \"dsubu\\t%0,%z1,%2\";
1367 }"
1368 [(set_attr "type" "darith")
1369 (set_attr "mode" "DI")
1370 (set_attr "length" "1")])
1371
1372 ;; For the mips16, we need to recognize stack pointer subtractions
1373 ;; explicitly, since we don't have a constraint for $sp. These insns
1374 ;; will be generated by the save_restore_insns functions.
1375
1376 (define_insn ""
1377 [(set (reg:DI 29)
1378 (minus:DI (reg:DI 29)
1379 (match_operand:DI 0 "small_int" "I")))]
1380 "TARGET_MIPS16
1381 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1382 "daddu\\t%$,%$,%n0"
1383 [(set_attr "type" "arith")
1384 (set_attr "mode" "DI")
1385 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1386 (const_int 1)
1387 (const_int 2)))])
1388
1389 (define_insn ""
1390 [(set (match_operand:DI 0 "register_operand" "=d")
1391 (minus:DI (reg:DI 29)
1392 (match_operand:DI 1 "small_int" "I")))]
1393 "TARGET_MIPS16
1394 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1395 "daddu\\t%0,%$,%n1"
1396 [(set_attr "type" "arith")
1397 (set_attr "mode" "DI")
1398 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1399 (const_int 1)
1400 (const_int 2)))])
1401
1402 (define_insn ""
1403 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1404 (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1405 (match_operand:DI 2 "arith_operand" "I,O,d")))]
1406 "TARGET_MIPS16
1407 && (GET_CODE (operands[2]) != CONST_INT
1408 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1409 "*
1410 {
1411 if (REGNO (operands[0]) == REGNO (operands[1]))
1412 return \"dsubu\\t%0,%2\";
1413 return \"dsubu\\t%0,%1,%2\";
1414 }"
1415 [(set_attr "type" "arith")
1416 (set_attr "mode" "DI")
1417 (set_attr_alternative "length"
1418 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1419 (const_int 1)
1420 (const_int 2))
1421 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1422 (const_int 1)
1423 (const_int 2))
1424 (const_int 1)])])
1425
1426 ;; On the mips16, we can sometimes split an add of a constant which is
1427 ;; a 4 byte instruction into two adds which are both 2 byte
1428 ;; instructions. There are two cases: one where we are adding a
1429 ;; constant plus a register to another register, and one where we are
1430 ;; simply adding a constant to a register.
1431
1432 (define_split
1433 [(set (match_operand:DI 0 "register_operand" "")
1434 (minus:DI (match_dup 0)
1435 (match_operand:DI 1 "const_int_operand" "")))]
1436 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1437 && GET_CODE (operands[0]) == REG
1438 && M16_REG_P (REGNO (operands[0]))
1439 && GET_CODE (operands[1]) == CONST_INT
1440 && ((INTVAL (operands[1]) > 0x10
1441 && INTVAL (operands[1]) <= 0x10 + 0x10)
1442 || (INTVAL (operands[1]) < - 0xf
1443 && INTVAL (operands[1]) >= - 0xf - 0xf))"
1444 [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1445 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1446 "
1447 {
1448 HOST_WIDE_INT val = INTVAL (operands[1]);
1449
1450 if (val >= 0)
1451 {
1452 operands[1] = GEN_INT (0xf);
1453 operands[2] = GEN_INT (val - 0xf);
1454 }
1455 else
1456 {
1457 operands[1] = GEN_INT (- 0x10);
1458 operands[2] = GEN_INT (val + 0x10);
1459 }
1460 }")
1461
1462 (define_split
1463 [(set (match_operand:DI 0 "register_operand" "")
1464 (minus:DI (match_operand:DI 1 "register_operand" "")
1465 (match_operand:DI 2 "const_int_operand" "")))]
1466 "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1467 && GET_CODE (operands[0]) == REG
1468 && M16_REG_P (REGNO (operands[0]))
1469 && GET_CODE (operands[1]) == REG
1470 && M16_REG_P (REGNO (operands[1]))
1471 && REGNO (operands[0]) != REGNO (operands[1])
1472 && GET_CODE (operands[2]) == CONST_INT
1473 && ((INTVAL (operands[2]) > 0x8
1474 && INTVAL (operands[2]) <= 0x8 + 0x10)
1475 || (INTVAL (operands[2]) < - 0x7
1476 && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1477 [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1478 (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1479 "
1480 {
1481 HOST_WIDE_INT val = INTVAL (operands[2]);
1482
1483 if (val >= 0)
1484 {
1485 operands[2] = GEN_INT (0x8);
1486 operands[3] = GEN_INT (val - 0x8);
1487 }
1488 else
1489 {
1490 operands[2] = GEN_INT (- 0x7);
1491 operands[3] = GEN_INT (val + 0x7);
1492 }
1493 }")
1494
1495 (define_insn "subsi3_internal_2"
1496 [(set (match_operand:DI 0 "register_operand" "=d")
1497 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1498 (match_operand:SI 2 "arith_operand" "dI"))))]
1499 "TARGET_64BIT && !TARGET_MIPS16
1500 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1501 "*
1502 {
1503 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1504 ? \"addu\\t%0,%z1,%n2\"
1505 : \"subu\\t%0,%z1,%2\";
1506 }"
1507 [(set_attr "type" "arith")
1508 (set_attr "mode" "DI")
1509 (set_attr "length" "1")])
1510
1511 (define_insn ""
1512 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1513 (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1514 (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1515 "TARGET_64BIT && TARGET_MIPS16
1516 && (GET_CODE (operands[2]) != CONST_INT
1517 || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1518 "*
1519 {
1520 if (REGNO (operands[0]) == REGNO (operands[1]))
1521 return \"subu\\t%0,%2\";
1522 return \"subu\\t%0,%1,%2\";
1523 }"
1524 [(set_attr "type" "arith")
1525 (set_attr "mode" "SI")
1526 (set_attr_alternative "length"
1527 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1528 (const_int 1)
1529 (const_int 2))
1530 (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1531 (const_int 1)
1532 (const_int 2))
1533 (const_int 1)])])
1534
1535
1536 \f
1537 ;;
1538 ;; ....................
1539 ;;
1540 ;; MULTIPLICATION
1541 ;;
1542 ;; ....................
1543 ;;
1544
1545 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1546 ;; operands may corrupt immediately following multiplies. This is a
1547 ;; simple fix to insert NOPs.
1548
1549 (define_expand "muldf3"
1550 [(set (match_operand:DF 0 "register_operand" "=f")
1551 (mult:DF (match_operand:DF 1 "register_operand" "f")
1552 (match_operand:DF 2 "register_operand" "f")))]
1553 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1554 "
1555 {
1556 if (mips_cpu != PROCESSOR_R4300)
1557 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1558 else
1559 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1560 DONE;
1561 }")
1562
1563 (define_insn "muldf3_internal"
1564 [(set (match_operand:DF 0 "register_operand" "=f")
1565 (mult:DF (match_operand:DF 1 "register_operand" "f")
1566 (match_operand:DF 2 "register_operand" "f")))]
1567 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
1568 "mul.d\\t%0,%1,%2"
1569 [(set_attr "type" "fmul")
1570 (set_attr "mode" "DF")
1571 (set_attr "length" "1")])
1572
1573 (define_insn "muldf3_r4300"
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 "*
1579 {
1580 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1581 if (TARGET_4300_MUL_FIX)
1582 output_asm_insn (\"nop\", operands);
1583 return \"\";
1584 }"
1585 [(set_attr "type" "fmul")
1586 (set_attr "mode" "DF")
1587 (set_attr "length" "2")]) ;; mul.d + nop
1588
1589 (define_expand "mulsf3"
1590 [(set (match_operand:SF 0 "register_operand" "=f")
1591 (mult:SF (match_operand:SF 1 "register_operand" "f")
1592 (match_operand:SF 2 "register_operand" "f")))]
1593 "TARGET_HARD_FLOAT"
1594 "
1595 {
1596 if (mips_cpu != PROCESSOR_R4300)
1597 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1598 else
1599 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1600 DONE;
1601 }")
1602
1603 (define_insn "mulsf3_internal"
1604 [(set (match_operand:SF 0 "register_operand" "=f")
1605 (mult:SF (match_operand:SF 1 "register_operand" "f")
1606 (match_operand:SF 2 "register_operand" "f")))]
1607 "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
1608 "mul.s\\t%0,%1,%2"
1609 [(set_attr "type" "fmul")
1610 (set_attr "mode" "SF")
1611 (set_attr "length" "1")])
1612
1613 (define_insn "mulsf3_r4300"
1614 [(set (match_operand:SF 0 "register_operand" "=f")
1615 (mult:SF (match_operand:SF 1 "register_operand" "f")
1616 (match_operand:SF 2 "register_operand" "f")))]
1617 "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1618 "*
1619 {
1620 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1621 if (TARGET_4300_MUL_FIX)
1622 output_asm_insn (\"nop\", operands);
1623 return \"\";
1624 }"
1625 [(set_attr "type" "fmul")
1626 (set_attr "mode" "SF")
1627 (set_attr "length" "2")]) ;; mul.s + nop
1628
1629 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1630 ;; a multiply is in progress, it may give an incorrect result. Avoid
1631 ;; this by keeping the mflo with the mult on the R4000.
1632
1633 (define_expand "mulsi3"
1634 [(set (match_operand:SI 0 "register_operand" "=l")
1635 (mult:SI (match_operand:SI 1 "register_operand" "d")
1636 (match_operand:SI 2 "register_operand" "d")))
1637 (clobber (match_scratch:SI 3 "=h"))
1638 (clobber (match_scratch:SI 4 "=a"))]
1639 ""
1640 "
1641 {
1642 if (GENERATE_MULT3)
1643 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1644 else if (TARGET_MAD)
1645 emit_insn (gen_mulsi3_r4650 (operands[0], operands[1], operands[2]));
1646 else if (mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16)
1647 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1648 else
1649 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1650 DONE;
1651 }")
1652
1653 (define_insn "mulsi3_mult3"
1654 [(set (match_operand:SI 0 "register_operand" "=d")
1655 (mult:SI (match_operand:SI 1 "register_operand" "d")
1656 (match_operand:SI 2 "register_operand" "d")))
1657 (clobber (match_scratch:SI 3 "=h"))
1658 (clobber (match_scratch:SI 4 "=l"))
1659 (clobber (match_scratch:SI 5 "=a"))]
1660 "GENERATE_MULT3"
1661 "mult\\t%0,%1,%2"
1662 [(set_attr "type" "imul")
1663 (set_attr "mode" "SI")
1664 (set_attr "length" "1")])
1665
1666 (define_insn "mulsi3_internal"
1667 [(set (match_operand:SI 0 "register_operand" "=l")
1668 (mult:SI (match_operand:SI 1 "register_operand" "d")
1669 (match_operand:SI 2 "register_operand" "d")))
1670 (clobber (match_scratch:SI 3 "=h"))
1671 (clobber (match_scratch:SI 4 "=a"))]
1672 "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16"
1673 "mult\\t%1,%2"
1674 [(set_attr "type" "imul")
1675 (set_attr "mode" "SI")
1676 (set_attr "length" "1")])
1677
1678 (define_insn "mulsi3_r4000"
1679 [(set (match_operand:SI 0 "register_operand" "=d")
1680 (mult:SI (match_operand:SI 1 "register_operand" "d")
1681 (match_operand:SI 2 "register_operand" "d")))
1682 (clobber (match_scratch:SI 3 "=h"))
1683 (clobber (match_scratch:SI 4 "=l"))
1684 (clobber (match_scratch:SI 5 "=a"))]
1685 "mips_cpu == PROCESSOR_R4000 && !TARGET_MIPS16"
1686 "*
1687 {
1688 rtx xoperands[10];
1689
1690 xoperands[0] = operands[0];
1691 xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1692
1693 output_asm_insn (\"mult\\t%1,%2\", operands);
1694 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1695 return \"\";
1696 }"
1697 [(set_attr "type" "imul")
1698 (set_attr "mode" "SI")
1699 (set_attr "length" "3")]) ;; mult + mflo + delay
1700
1701 (define_insn "mulsi3_r4650"
1702 [(set (match_operand:SI 0 "register_operand" "=d")
1703 (mult:SI (match_operand:SI 1 "register_operand" "d")
1704 (match_operand:SI 2 "register_operand" "d")))
1705 (clobber (match_scratch:SI 3 "=h"))
1706 (clobber (match_scratch:SI 4 "=l"))
1707 (clobber (match_scratch:SI 5 "=a"))]
1708 "TARGET_MAD"
1709 "mul\\t%0,%1,%2"
1710 [(set_attr "type" "imul")
1711 (set_attr "mode" "SI")
1712 (set_attr "length" "1")])
1713
1714 (define_expand "muldi3"
1715 [(set (match_operand:DI 0 "register_operand" "=l")
1716 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1717 (match_operand:DI 2 "register_operand" "d")))
1718 (clobber (match_scratch:DI 3 "=h"))
1719 (clobber (match_scratch:DI 4 "=a"))]
1720 "TARGET_64BIT"
1721 "
1722 {
1723 if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)
1724 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1725 else
1726 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1727 DONE;
1728 }")
1729
1730 ;; Don't accept both operands using se_register_operand, because if
1731 ;; both operands are sign extended we would prefer to use mult in the
1732 ;; mulsidi3 pattern. Commutativity should permit either operand to be
1733 ;; sign extended.
1734
1735 (define_insn "muldi3_internal"
1736 [(set (match_operand:DI 0 "register_operand" "=l")
1737 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1738 (match_operand:DI 2 "register_operand" "d")))
1739 (clobber (match_scratch:DI 3 "=h"))
1740 (clobber (match_scratch:DI 4 "=a"))]
1741 "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16"
1742 "dmult\\t%1,%2"
1743 [(set_attr "type" "imul")
1744 (set_attr "mode" "DI")
1745 (set_attr "length" "1")])
1746
1747 (define_insn "muldi3_internal2"
1748 [(set (match_operand:DI 0 "register_operand" "=d")
1749 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1750 (match_operand:DI 2 "register_operand" "d")))
1751 (clobber (match_scratch:DI 3 "=h"))
1752 (clobber (match_scratch:DI 4 "=l"))
1753 (clobber (match_scratch:DI 5 "=a"))]
1754 "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)"
1755 "*
1756 {
1757 if (GENERATE_MULT3)
1758 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1759 else
1760 {
1761 rtx xoperands[10];
1762
1763 xoperands[0] = operands[0];
1764 xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1765
1766 output_asm_insn (\"dmult\\t%1,%2\", operands);
1767 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1768 }
1769 return \"\";
1770 }"
1771 [(set_attr "type" "imul")
1772 (set_attr "mode" "DI")
1773 (set (attr "length")
1774 (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1775 (const_int 1)
1776 (const_int 3)))]) ;; mult + mflo + delay
1777
1778 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1779
1780 (define_expand "mulsidi3"
1781 [(set (match_operand:DI 0 "register_operand" "=x")
1782 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1783 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1784 ""
1785 "
1786 {
1787 if (TARGET_64BIT)
1788 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
1789 else
1790 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
1791 DONE;
1792 }")
1793
1794 (define_insn "mulsidi3_internal"
1795 [(set (match_operand:DI 0 "register_operand" "=x")
1796 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1797 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1798 (clobber (match_scratch:SI 3 "=a"))]
1799 "!TARGET_64BIT"
1800 "mult\\t%1,%2"
1801 [(set_attr "type" "imul")
1802 (set_attr "mode" "SI")
1803 (set_attr "length" "1")])
1804
1805 (define_insn "mulsidi3_64bit"
1806 [(set (match_operand:DI 0 "register_operand" "=a")
1807 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1808 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1809 (clobber (match_scratch:DI 3 "=l"))
1810 (clobber (match_scratch:DI 4 "=h"))]
1811 "TARGET_64BIT"
1812 "mult\\t%1,%2"
1813 [(set_attr "type" "imul")
1814 (set_attr "mode" "SI")
1815 (set_attr "length" "1")])
1816
1817 (define_insn "smulsi3_highpart"
1818 [(set (match_operand:SI 0 "register_operand" "=h")
1819 (truncate:SI
1820 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1821 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1822 (const_int 32))))
1823 (clobber (match_scratch:SI 3 "=l"))
1824 (clobber (match_scratch:SI 4 "=a"))]
1825 ""
1826 "mult\\t%1,%2"
1827 [(set_attr "type" "imul")
1828 (set_attr "mode" "SI")
1829 (set_attr "length" "1")])
1830
1831 (define_expand "umulsidi3"
1832 [(set (match_operand:DI 0 "register_operand" "=x")
1833 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1834 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1835 ""
1836 "
1837 {
1838 if (TARGET_64BIT)
1839 emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
1840 else
1841 emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
1842 DONE;
1843 }")
1844
1845 (define_insn "umulsidi3_internal"
1846 [(set (match_operand:DI 0 "register_operand" "=x")
1847 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1848 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1849 (clobber (match_scratch:SI 3 "=a"))]
1850 "!TARGET_64BIT"
1851 "multu\\t%1,%2"
1852 [(set_attr "type" "imul")
1853 (set_attr "mode" "SI")
1854 (set_attr "length" "1")])
1855
1856 (define_insn "umulsidi3_64bit"
1857 [(set (match_operand:DI 0 "register_operand" "=a")
1858 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1859 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1860 (clobber (match_scratch:DI 3 "=l"))
1861 (clobber (match_scratch:DI 4 "=h"))]
1862 "TARGET_64BIT"
1863 "multu\\t%1,%2"
1864 [(set_attr "type" "imul")
1865 (set_attr "mode" "SI")
1866 (set_attr "length" "1")])
1867
1868 (define_insn "umulsi3_highpart"
1869 [(set (match_operand:SI 0 "register_operand" "=h")
1870 (truncate:SI
1871 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1872 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1873 (const_int 32))))
1874 (clobber (match_scratch:SI 3 "=l"))
1875 (clobber (match_scratch:SI 4 "=a"))]
1876 ""
1877 "multu\\t%1,%2"
1878 [(set_attr "type" "imul")
1879 (set_attr "mode" "SI")
1880 (set_attr "length" "1")])
1881
1882 (define_insn "smuldi3_highpart"
1883 [(set (match_operand:DI 0 "register_operand" "=h")
1884 (truncate:DI
1885 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1886 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1887 (const_int 64))))
1888 (clobber (match_scratch:DI 3 "=l"))
1889 (clobber (match_scratch:DI 4 "=a"))]
1890 "TARGET_64BIT"
1891 "dmult\\t%1,%2"
1892 [(set_attr "type" "imul")
1893 (set_attr "mode" "DI")
1894 (set_attr "length" "1")])
1895
1896 (define_insn "umuldi3_highpart"
1897 [(set (match_operand:DI 0 "register_operand" "=h")
1898 (truncate:DI
1899 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1900 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1901 (const_int 64))))
1902 (clobber (match_scratch:DI 3 "=l"))
1903 (clobber (match_scratch:DI 4 "=a"))]
1904 "TARGET_64BIT"
1905 "dmultu\\t%1,%2"
1906 [(set_attr "type" "imul")
1907 (set_attr "mode" "DI")
1908 (set_attr "length" "1")])
1909
1910 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1911 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1912
1913 (define_insn "madsi"
1914 [(set (match_operand:SI 0 "register_operand" "+l")
1915 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1916 (match_operand:SI 2 "register_operand" "d"))
1917 (match_dup 0)))
1918 (clobber (match_scratch:SI 3 "=h"))
1919 (clobber (match_scratch:SI 4 "=a"))]
1920 "TARGET_MAD || GENERATE_MADD"
1921 "*
1922 {
1923 if (TARGET_MAD)
1924 return \"mad\\t%1,%2\";
1925 else
1926 return \"madd\\t%1,%2\";
1927 }"
1928 [(set_attr "type" "imul")
1929 (set_attr "mode" "SI")
1930 (set_attr "length" "1")])
1931
1932 (define_insn "maddi"
1933 [(set (match_operand:DI 0 "register_operand" "+x")
1934 (plus:DI (mult:DI (sign_extend:DI
1935 (match_operand:SI 1 "register_operand" "d"))
1936 (sign_extend:DI
1937 (match_operand:SI 2 "register_operand" "d")))
1938 (match_dup 0)))
1939 (clobber (match_scratch:SI 3 "=a"))]
1940 "TARGET_MAD && ! TARGET_64BIT"
1941 "mad\\t%1,%2"
1942 [(set_attr "type" "imul")
1943 (set_attr "mode" "SI")
1944 (set_attr "length" "1")])
1945
1946 (define_insn "maddi_64bit"
1947 [(set (match_operand:DI 0 "register_operand" "+a")
1948 (plus:DI (mult:DI (sign_extend:DI
1949 (match_operand:SI 1 "register_operand" "d"))
1950 (sign_extend:DI
1951 (match_operand:SI 2 "register_operand" "d")))
1952 (match_dup 0)))
1953 (clobber (match_scratch:DI 3 "=l"))
1954 (clobber (match_scratch:DI 4 "=h"))]
1955 "TARGET_MAD && TARGET_64BIT"
1956 "mad\\t%1,%2"
1957 [(set_attr "type" "imul")
1958 (set_attr "mode" "SI")
1959 (set_attr "length" "1")])
1960
1961 (define_insn "umaddi"
1962 [(set (match_operand:DI 0 "register_operand" "+x")
1963 (plus:DI (mult:DI (zero_extend:DI
1964 (match_operand:SI 1 "register_operand" "d"))
1965 (zero_extend:DI
1966 (match_operand:SI 2 "register_operand" "d")))
1967 (match_dup 0)))
1968 (clobber (match_scratch:SI 3 "=a"))]
1969 "TARGET_MAD && ! TARGET_64BIT"
1970 "madu\\t%1,%2"
1971 [(set_attr "type" "imul")
1972 (set_attr "mode" "SI")
1973 (set_attr "length" "1")])
1974
1975 (define_insn "umaddi_64bit"
1976 [(set (match_operand:DI 0 "register_operand" "+a")
1977 (plus:DI (mult:DI (zero_extend:DI
1978 (match_operand:SI 1 "register_operand" "d"))
1979 (zero_extend:DI
1980 (match_operand:SI 2 "register_operand" "d")))
1981 (match_dup 0)))
1982 (clobber (match_scratch:DI 3 "=l"))
1983 (clobber (match_scratch:DI 4 "=h"))]
1984 "TARGET_MAD && TARGET_64BIT"
1985 "madu\\t%1,%2"
1986 [(set_attr "type" "imul")
1987 (set_attr "mode" "SI")
1988 (set_attr "length" "1")])
1989
1990 (define_insn "madd3"
1991 [(set (match_operand:SI 0 "register_operand" "=d")
1992 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1993 (match_operand:SI 2 "register_operand" "d"))
1994 (match_operand:SI 3 "register_operand" "l")))
1995 (clobber (match_scratch:SI 4 "=l"))
1996 (clobber (match_scratch:SI 5 "=h"))
1997 (clobber (match_scratch:SI 6 "=a"))]
1998 "GENERATE_MADD"
1999 "madd\\t%0,%1,%2"
2000 [(set_attr "type" "imul")
2001 (set_attr "mode" "SI")
2002 (set_attr "length" "1")])
2003
2004 ;; Floating point multiply accumulate instructions.
2005
2006 (define_insn ""
2007 [(set (match_operand:DF 0 "register_operand" "=f")
2008 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2009 (match_operand:DF 2 "register_operand" "f"))
2010 (match_operand:DF 3 "register_operand" "f")))]
2011 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2012 "madd.d\\t%0,%3,%1,%2"
2013 [(set_attr "type" "fmadd")
2014 (set_attr "mode" "DF")
2015 (set_attr "length" "1")])
2016
2017 (define_insn ""
2018 [(set (match_operand:SF 0 "register_operand" "=f")
2019 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2020 (match_operand:SF 2 "register_operand" "f"))
2021 (match_operand:SF 3 "register_operand" "f")))]
2022 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2023 "madd.s\\t%0,%3,%1,%2"
2024 [(set_attr "type" "fmadd")
2025 (set_attr "mode" "SF")
2026 (set_attr "length" "1")])
2027
2028 (define_insn ""
2029 [(set (match_operand:DF 0 "register_operand" "=f")
2030 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2031 (match_operand:DF 2 "register_operand" "f"))
2032 (match_operand:DF 3 "register_operand" "f")))]
2033 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2034 "msub.d\\t%0,%3,%1,%2"
2035 [(set_attr "type" "fmadd")
2036 (set_attr "mode" "DF")
2037 (set_attr "length" "1")])
2038
2039 (define_insn ""
2040 [(set (match_operand:SF 0 "register_operand" "=f")
2041 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2042 (match_operand:SF 2 "register_operand" "f"))
2043 (match_operand:SF 3 "register_operand" "f")))]
2044
2045 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2046 "msub.s\\t%0,%3,%1,%2"
2047 [(set_attr "type" "fmadd")
2048 (set_attr "mode" "SF")
2049 (set_attr "length" "1")])
2050
2051 (define_insn ""
2052 [(set (match_operand:DF 0 "register_operand" "=f")
2053 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2054 (match_operand:DF 2 "register_operand" "f"))
2055 (match_operand:DF 3 "register_operand" "f"))))]
2056 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2057 "nmadd.d\\t%0,%3,%1,%2"
2058 [(set_attr "type" "fmadd")
2059 (set_attr "mode" "DF")
2060 (set_attr "length" "1")])
2061
2062 (define_insn ""
2063 [(set (match_operand:SF 0 "register_operand" "=f")
2064 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2065 (match_operand:SF 2 "register_operand" "f"))
2066 (match_operand:SF 3 "register_operand" "f"))))]
2067 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2068 "nmadd.s\\t%0,%3,%1,%2"
2069 [(set_attr "type" "fmadd")
2070 (set_attr "mode" "SF")
2071 (set_attr "length" "1")])
2072
2073 (define_insn ""
2074 [(set (match_operand:DF 0 "register_operand" "=f")
2075 (minus:DF (match_operand:DF 1 "register_operand" "f")
2076 (mult:DF (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 "nmsub.d\\t%0,%1,%2,%3"
2080 [(set_attr "type" "fmadd")
2081 (set_attr "mode" "DF")
2082 (set_attr "length" "1")])
2083
2084 (define_insn ""
2085 [(set (match_operand:SF 0 "register_operand" "=f")
2086 (minus:SF (match_operand:SF 1 "register_operand" "f")
2087 (mult:SF (match_operand:SF 2 "register_operand" "f")
2088 (match_operand:SF 3 "register_operand" "f"))))]
2089 "mips_isa >= 4 && TARGET_HARD_FLOAT"
2090 "nmsub.s\\t%0,%1,%2,%3"
2091 [(set_attr "type" "fmadd")
2092 (set_attr "mode" "SF")
2093 (set_attr "length" "1")])
2094 \f
2095 ;;
2096 ;; ....................
2097 ;;
2098 ;; DIVISION and REMAINDER
2099 ;;
2100 ;; ....................
2101 ;;
2102
2103 (define_insn "divdf3"
2104 [(set (match_operand:DF 0 "register_operand" "=f")
2105 (div:DF (match_operand:DF 1 "register_operand" "f")
2106 (match_operand:DF 2 "register_operand" "f")))]
2107 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2108 "div.d\\t%0,%1,%2"
2109 [(set_attr "type" "fdiv")
2110 (set_attr "mode" "DF")
2111 (set_attr "length" "1")])
2112
2113 (define_insn "divsf3"
2114 [(set (match_operand:SF 0 "register_operand" "=f")
2115 (div:SF (match_operand:SF 1 "register_operand" "f")
2116 (match_operand:SF 2 "register_operand" "f")))]
2117 "TARGET_HARD_FLOAT"
2118 "div.s\\t%0,%1,%2"
2119 [(set_attr "type" "fdiv")
2120 (set_attr "mode" "SF")
2121 (set_attr "length" "1")])
2122
2123 (define_insn ""
2124 [(set (match_operand:DF 0 "register_operand" "=f")
2125 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2126 (match_operand:DF 2 "register_operand" "f")))]
2127 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2128 "recip.d\\t%0,%2"
2129 [(set_attr "type" "fdiv")
2130 (set_attr "mode" "DF")
2131 (set_attr "length" "1")])
2132
2133 (define_insn ""
2134 [(set (match_operand:SF 0 "register_operand" "=f")
2135 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2136 (match_operand:SF 2 "register_operand" "f")))]
2137 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2138 "recip.s\\t%0,%2"
2139 [(set_attr "type" "fdiv")
2140 (set_attr "mode" "SF")
2141 (set_attr "length" "1")])
2142
2143 ;; If optimizing, prefer the divmod functions over separate div and
2144 ;; mod functions, since this will allow using one instruction for both
2145 ;; the quotient and remainder. At present, the divmod is not moved out
2146 ;; of loops if it is constant within the loop, so allow -mdebugc to
2147 ;; use the old method of doing things.
2148
2149 ;; 64 is the multiply/divide hi register
2150 ;; 65 is the multiply/divide lo register
2151
2152 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2153 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2154 ;; available.
2155
2156 (define_insn "divmodsi4"
2157 [(set (match_operand:SI 0 "register_operand" "=d")
2158 (div:SI (match_operand:SI 1 "register_operand" "d")
2159 (match_operand:SI 2 "register_operand" "d")))
2160 (set (match_operand:SI 3 "register_operand" "=d")
2161 (mod:SI (match_dup 1)
2162 (match_dup 2)))
2163 (clobber (match_scratch:SI 4 "=l"))
2164 (clobber (match_scratch:SI 5 "=h"))
2165 (clobber (match_scratch:SI 6 "=a"))]
2166 "optimize"
2167 "*
2168 {
2169 if (find_reg_note (insn, REG_UNUSED, operands[3]))
2170 return \"div\\t%0,%1,%2\";
2171
2172 if (find_reg_note (insn, REG_UNUSED, operands[0]))
2173 return \"rem\\t%3,%1,%2\";
2174
2175 return \"div\\t%0,%1,%2\;mfhi\\t%3\";
2176 }"
2177 [(set_attr "type" "idiv")
2178 (set_attr "mode" "SI")
2179 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
2180
2181 (define_insn "divmoddi4"
2182 [(set (match_operand:DI 0 "register_operand" "=d")
2183 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2184 (match_operand:DI 2 "se_register_operand" "d")))
2185 (set (match_operand:DI 3 "register_operand" "=d")
2186 (mod:DI (match_dup 1)
2187 (match_dup 2)))
2188 (clobber (match_scratch:DI 4 "=l"))
2189 (clobber (match_scratch:DI 5 "=h"))
2190 (clobber (match_scratch:DI 6 "=a"))]
2191 "TARGET_64BIT && optimize"
2192 "*
2193 {
2194 if (find_reg_note (insn, REG_UNUSED, operands[3]))
2195 return \"ddiv\\t%0,%1,%2\";
2196
2197 if (find_reg_note (insn, REG_UNUSED, operands[0]))
2198 return \"drem\\t%3,%1,%2\";
2199
2200 return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
2201 }"
2202 [(set_attr "type" "idiv")
2203 (set_attr "mode" "DI")
2204 (set_attr "length" "15")]) ;; various tests for dividing by 0 and such
2205
2206 (define_insn "udivmodsi4"
2207 [(set (match_operand:SI 0 "register_operand" "=d")
2208 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2209 (match_operand:SI 2 "register_operand" "d")))
2210 (set (match_operand:SI 3 "register_operand" "=d")
2211 (umod:SI (match_dup 1)
2212 (match_dup 2)))
2213 (clobber (match_scratch:SI 4 "=l"))
2214 (clobber (match_scratch:SI 5 "=h"))
2215 (clobber (match_scratch:SI 6 "=a"))]
2216 "optimize"
2217 "*
2218 {
2219 if (find_reg_note (insn, REG_UNUSED, operands[3]))
2220 return \"divu\\t%0,%1,%2\";
2221
2222 if (find_reg_note (insn, REG_UNUSED, operands[0]))
2223 return \"remu\\t%3,%1,%2\";
2224
2225 return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
2226 }"
2227 [(set_attr "type" "idiv")
2228 (set_attr "mode" "SI")
2229 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
2230
2231 (define_insn "udivmoddi4"
2232 [(set (match_operand:DI 0 "register_operand" "=d")
2233 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2234 (match_operand:DI 2 "se_register_operand" "d")))
2235 (set (match_operand:DI 3 "register_operand" "=d")
2236 (umod:DI (match_dup 1)
2237 (match_dup 2)))
2238 (clobber (match_scratch:DI 4 "=l"))
2239 (clobber (match_scratch:DI 5 "=h"))
2240 (clobber (match_scratch:DI 6 "=a"))]
2241 "TARGET_64BIT && optimize"
2242 "*
2243 {
2244 if (find_reg_note (insn, REG_UNUSED, operands[3]))
2245 return \"ddivu\\t%0,%1,%2\";
2246
2247 if (find_reg_note (insn, REG_UNUSED, operands[0]))
2248 return \"dremu\\t%3,%1,%2\";
2249
2250 return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
2251 }"
2252 [(set_attr "type" "idiv")
2253 (set_attr "mode" "DI")
2254 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
2255
2256 (define_expand "divsi3"
2257 [(set (match_operand:SI 0 "register_operand" "=d")
2258 (div:SI (match_operand:SI 1 "register_operand" "d")
2259 (match_operand:SI 2 "nonmemory_operand" "di")))
2260 (clobber (match_scratch:SI 3 "=l"))
2261 (clobber (match_scratch:SI 4 "=h"))
2262 (clobber (match_scratch:SI 6 "=a"))]
2263 "!optimize"
2264 "
2265 {
2266 /* MIPS16 needs div/rem ops in registers. */
2267 if (TARGET_MIPS16)
2268 operands[2] = force_reg (SImode, operands[2]);
2269 }")
2270
2271 (define_insn "divsi3_internal"
2272 [(set (match_operand:SI 0 "register_operand" "=d")
2273 (div:SI (match_operand:SI 1 "register_operand" "d")
2274 (match_operand:SI 2 "nonmemory_operand" "di")))]
2275 "!optimize"
2276 "div\\t%0,%1,%2"
2277 [(set_attr "type" "idiv")
2278 (set_attr "mode" "SI")
2279 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
2280
2281 (define_expand "divdi3"
2282 [(set (match_operand:DI 0 "register_operand" "=d")
2283 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2284 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2285 (clobber (match_scratch:DI 3 "=l"))
2286 (clobber (match_scratch:DI 4 "=h"))
2287 (clobber (match_scratch:DI 6 "=a"))]
2288 "TARGET_64BIT && !optimize"
2289 "
2290 {
2291 /* MIPS16 needs div/rem ops in registers. */
2292 if (TARGET_MIPS16)
2293 operands[2] = force_reg (DImode, operands[2]);
2294 }")
2295
2296 (define_insn "divdi3_internal"
2297 [(set (match_operand:DI 0 "register_operand" "=d")
2298 (div:DI (match_operand:DI 1 "se_register_operand" "d")
2299 (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2300 "TARGET_64BIT && !optimize"
2301 "ddiv\\t%0,%1,%2"
2302 [(set_attr "type" "idiv")
2303 (set_attr "mode" "DI")
2304 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
2305
2306 (define_expand "modsi3"
2307 [(set (match_operand:SI 0 "register_operand" "=d")
2308 (mod:SI (match_operand:SI 1 "register_operand" "d")
2309 (match_operand:SI 2 "nonmemory_operand" "di")))
2310 (clobber (match_scratch:SI 3 "=l"))
2311 (clobber (match_scratch:SI 4 "=h"))
2312 (clobber (match_scratch:SI 6 "=a"))]
2313 "!optimize"
2314 "
2315 {
2316 /* MIPS16 needs div/rem ops in registers. */
2317 if (TARGET_MIPS16)
2318 operands[2] = force_reg (SImode, operands[2]);
2319 }")
2320
2321 (define_insn "modsi3_internal"
2322 [(set (match_operand:SI 0 "register_operand" "=d")
2323 (mod:SI (match_operand:SI 1 "register_operand" "d")
2324 (match_operand:SI 2 "nonmemory_operand" "di")))]
2325 "!optimize"
2326 "rem\\t%0,%1,%2"
2327 [(set_attr "type" "idiv")
2328 (set_attr "mode" "SI")
2329 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
2330
2331 (define_expand "moddi3"
2332 [(set (match_operand:DI 0 "register_operand" "=d")
2333 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2334 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2335 (clobber (match_scratch:DI 3 "=l"))
2336 (clobber (match_scratch:DI 4 "=h"))
2337 (clobber (match_scratch:DI 6 "=a"))]
2338 "TARGET_64BIT && !optimize"
2339 "
2340 {
2341 /* MIPS16 needs div/rem ops in registers. */
2342 if (TARGET_MIPS16)
2343 operands[2] = force_reg (DImode, operands[2]);
2344 }")
2345
2346 (define_insn "moddi3_internal"
2347 [(set (match_operand:DI 0 "register_operand" "=d")
2348 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2349 (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2350 "TARGET_64BIT && !optimize"
2351 "drem\\t%0,%1,%2"
2352 [(set_attr "type" "idiv")
2353 (set_attr "mode" "DI")
2354 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
2355
2356 (define_expand "udivsi3"
2357 [(set (match_operand:SI 0 "register_operand" "=d")
2358 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2359 (match_operand:SI 2 "nonmemory_operand" "di")))
2360 (clobber (match_scratch:SI 3 "=l"))
2361 (clobber (match_scratch:SI 4 "=h"))
2362 (clobber (match_scratch:SI 6 "=a"))]
2363 "!optimize"
2364 "
2365 {
2366 /* MIPS16 needs div/rem ops in registers. */
2367 if (TARGET_MIPS16)
2368 operands[2] = force_reg (SImode, operands[2]);
2369 }")
2370
2371 (define_insn "udivsi3_internal"
2372 [(set (match_operand:SI 0 "register_operand" "=d")
2373 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2374 (match_operand:SI 2 "nonmemory_operand" "di")))]
2375 "!optimize"
2376 "divu\\t%0,%1,%2"
2377 [(set_attr "type" "idiv")
2378 (set_attr "mode" "SI")
2379 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
2380
2381 (define_expand "udivdi3"
2382 [(set (match_operand:DI 0 "register_operand" "=d")
2383 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2384 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2385 (clobber (match_scratch:DI 3 "=l"))
2386 (clobber (match_scratch:DI 4 "=h"))
2387 (clobber (match_scratch:DI 6 "=a"))]
2388 "TARGET_64BIT && !optimize"
2389 "
2390 {
2391 /* MIPS16 needs div/rem ops in registers. */
2392 if (TARGET_MIPS16)
2393 operands[2] = force_reg (DImode, operands[2]);
2394 }")
2395
2396 (define_insn "udivdi3_internal"
2397 [(set (match_operand:DI 0 "register_operand" "=d")
2398 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2399 (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2400 "TARGET_64BIT && !optimize"
2401 "ddivu\\t%0,%1,%2"
2402 [(set_attr "type" "idiv")
2403 (set_attr "mode" "DI")
2404 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
2405
2406 (define_expand "umodsi3"
2407 [(set (match_operand:SI 0 "register_operand" "=d")
2408 (umod:SI (match_operand:SI 1 "register_operand" "d")
2409 (match_operand:SI 2 "nonmemory_operand" "di")))
2410 (clobber (match_scratch:SI 3 "=l"))
2411 (clobber (match_scratch:SI 4 "=h"))
2412 (clobber (match_scratch:SI 6 "=a"))]
2413 "!optimize"
2414 "
2415 {
2416 /* MIPS16 needs div/rem ops in registers. */
2417 if (TARGET_MIPS16)
2418 operands[2] = force_reg (SImode, operands[2]);
2419 }")
2420
2421 (define_insn "umodsi3_internal"
2422 [(set (match_operand:SI 0 "register_operand" "=d")
2423 (umod:SI (match_operand:SI 1 "register_operand" "d")
2424 (match_operand:SI 2 "nonmemory_operand" "di")))]
2425 "!optimize"
2426 "remu\\t%0,%1,%2"
2427 [(set_attr "type" "idiv")
2428 (set_attr "mode" "SI")
2429 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
2430
2431 (define_expand "umoddi3"
2432 [(set (match_operand:DI 0 "register_operand" "=d")
2433 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2434 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2435 (clobber (match_scratch:DI 3 "=l"))
2436 (clobber (match_scratch:DI 4 "=h"))
2437 (clobber (match_scratch:DI 6 "=a"))]
2438 "TARGET_64BIT && !optimize"
2439 "
2440 {
2441 /* MIPS16 needs div/rem ops in registers. */
2442 if (TARGET_MIPS16)
2443 operands[2] = force_reg (DImode, operands[2]);
2444 }")
2445
2446 (define_insn "umoddi3_internal"
2447 [(set (match_operand:DI 0 "register_operand" "=d")
2448 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2449 (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2450 "TARGET_64BIT && !optimize"
2451 "dremu\\t%0,%1,%2"
2452 [(set_attr "type" "idiv")
2453 (set_attr "mode" "DI")
2454 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
2455
2456 \f
2457 ;;
2458 ;; ....................
2459 ;;
2460 ;; SQUARE ROOT
2461 ;;
2462 ;; ....................
2463
2464 (define_insn "sqrtdf2"
2465 [(set (match_operand:DF 0 "register_operand" "=f")
2466 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2467 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2468 "sqrt.d\\t%0,%1"
2469 [(set_attr "type" "fsqrt")
2470 (set_attr "mode" "DF")
2471 (set_attr "length" "1")])
2472
2473 (define_insn "sqrtsf2"
2474 [(set (match_operand:SF 0 "register_operand" "=f")
2475 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2476 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2477 "sqrt.s\\t%0,%1"
2478 [(set_attr "type" "fsqrt")
2479 (set_attr "mode" "SF")
2480 (set_attr "length" "1")])
2481
2482 (define_insn ""
2483 [(set (match_operand:DF 0 "register_operand" "=f")
2484 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2485 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2486 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2487 "rsqrt.d\\t%0,%2"
2488 [(set_attr "type" "fsqrt")
2489 (set_attr "mode" "DF")
2490 (set_attr "length" "1")])
2491
2492 (define_insn ""
2493 [(set (match_operand:SF 0 "register_operand" "=f")
2494 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2495 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2496 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2497 "rsqrt.s\\t%0,%2"
2498 [(set_attr "type" "fsqrt")
2499 (set_attr "mode" "SF")
2500 (set_attr "length" "1")])
2501
2502 \f
2503 ;;
2504 ;; ....................
2505 ;;
2506 ;; ABSOLUTE VALUE
2507 ;;
2508 ;; ....................
2509
2510 ;; Do not use the integer abs macro instruction, since that signals an
2511 ;; exception on -2147483648 (sigh).
2512
2513 (define_insn "abssi2"
2514 [(set (match_operand:SI 0 "register_operand" "=d")
2515 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2516 "!TARGET_MIPS16"
2517 "*
2518 {
2519 dslots_jump_total++;
2520 dslots_jump_filled++;
2521 operands[2] = const0_rtx;
2522
2523 if (REGNO (operands[0]) == REGNO (operands[1]))
2524 {
2525 if (GENERATE_BRANCHLIKELY)
2526 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
2527 else
2528 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
2529 }
2530 else
2531 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
2532 }"
2533 [(set_attr "type" "multi")
2534 (set_attr "mode" "SI")
2535 (set_attr "length" "3")])
2536
2537 (define_insn "absdi2"
2538 [(set (match_operand:DI 0 "register_operand" "=d")
2539 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
2540 "TARGET_64BIT && !TARGET_MIPS16"
2541 "*
2542 {
2543 dslots_jump_total++;
2544 dslots_jump_filled++;
2545 operands[2] = const0_rtx;
2546
2547 if (REGNO (operands[0]) == REGNO (operands[1]))
2548 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
2549 else
2550 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
2551 }"
2552 [(set_attr "type" "multi")
2553 (set_attr "mode" "DI")
2554 (set_attr "length" "3")])
2555
2556 (define_insn "absdf2"
2557 [(set (match_operand:DF 0 "register_operand" "=f")
2558 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2559 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2560 "abs.d\\t%0,%1"
2561 [(set_attr "type" "fabs")
2562 (set_attr "mode" "DF")
2563 (set_attr "length" "1")])
2564
2565 (define_insn "abssf2"
2566 [(set (match_operand:SF 0 "register_operand" "=f")
2567 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2568 "TARGET_HARD_FLOAT"
2569 "abs.s\\t%0,%1"
2570 [(set_attr "type" "fabs")
2571 (set_attr "mode" "SF")
2572 (set_attr "length" "1")])
2573
2574 \f
2575 ;;
2576 ;; ....................
2577 ;;
2578 ;; FIND FIRST BIT INSTRUCTION
2579 ;;
2580 ;; ....................
2581 ;;
2582
2583 (define_insn "ffssi2"
2584 [(set (match_operand:SI 0 "register_operand" "=&d")
2585 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2586 (clobber (match_scratch:SI 2 "=&d"))
2587 (clobber (match_scratch:SI 3 "=&d"))]
2588 "!TARGET_MIPS16"
2589 "*
2590 {
2591 dslots_jump_total += 2;
2592 dslots_jump_filled += 2;
2593 operands[4] = const0_rtx;
2594
2595 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2596 return \"%(\\
2597 move\\t%0,%z4\\n\\
2598 \\tbeq\\t%1,%z4,2f\\n\\
2599 1:\\tand\\t%2,%1,0x0001\\n\\
2600 \\taddu\\t%0,%0,1\\n\\
2601 \\tbeq\\t%2,%z4,1b\\n\\
2602 \\tsrl\\t%1,%1,1\\n\\
2603 2:%)\";
2604
2605 return \"%(\\
2606 move\\t%0,%z4\\n\\
2607 \\tmove\\t%3,%1\\n\\
2608 \\tbeq\\t%3,%z4,2f\\n\\
2609 1:\\tand\\t%2,%3,0x0001\\n\\
2610 \\taddu\\t%0,%0,1\\n\\
2611 \\tbeq\\t%2,%z4,1b\\n\\
2612 \\tsrl\\t%3,%3,1\\n\\
2613 2:%)\";
2614 }"
2615 [(set_attr "type" "multi")
2616 (set_attr "mode" "SI")
2617 (set_attr "length" "6")])
2618
2619 (define_insn "ffsdi2"
2620 [(set (match_operand:DI 0 "register_operand" "=&d")
2621 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
2622 (clobber (match_scratch:DI 2 "=&d"))
2623 (clobber (match_scratch:DI 3 "=&d"))]
2624 "TARGET_64BIT && !TARGET_MIPS16"
2625 "*
2626 {
2627 dslots_jump_total += 2;
2628 dslots_jump_filled += 2;
2629 operands[4] = const0_rtx;
2630
2631 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2632 return \"%(\\
2633 move\\t%0,%z4\\n\\
2634 \\tbeq\\t%1,%z4,2f\\n\\
2635 1:\\tand\\t%2,%1,0x0001\\n\\
2636 \\tdaddu\\t%0,%0,1\\n\\
2637 \\tbeq\\t%2,%z4,1b\\n\\
2638 \\tdsrl\\t%1,%1,1\\n\\
2639 2:%)\";
2640
2641 return \"%(\\
2642 move\\t%0,%z4\\n\\
2643 \\tmove\\t%3,%1\\n\\
2644 \\tbeq\\t%3,%z4,2f\\n\\
2645 1:\\tand\\t%2,%3,0x0001\\n\\
2646 \\tdaddu\\t%0,%0,1\\n\\
2647 \\tbeq\\t%2,%z4,1b\\n\\
2648 \\tdsrl\\t%3,%3,1\\n\\
2649 2:%)\";
2650 }"
2651 [(set_attr "type" "multi")
2652 (set_attr "mode" "DI")
2653 (set_attr "length" "6")])
2654
2655 \f
2656 ;;
2657 ;; ....................
2658 ;;
2659 ;; NEGATION and ONE'S COMPLEMENT
2660 ;;
2661 ;; ....................
2662
2663 (define_insn "negsi2"
2664 [(set (match_operand:SI 0 "register_operand" "=d")
2665 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2666 ""
2667 "*
2668 {
2669 if (TARGET_MIPS16)
2670 return \"neg\\t%0,%1\";
2671 operands[2] = const0_rtx;
2672 return \"subu\\t%0,%z2,%1\";
2673 }"
2674 [(set_attr "type" "arith")
2675 (set_attr "mode" "SI")
2676 (set_attr "length" "1")])
2677
2678 (define_expand "negdi2"
2679 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2680 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
2681 (clobber (match_dup 2))])]
2682 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2683 "
2684 {
2685 if (TARGET_64BIT)
2686 {
2687 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2688 DONE;
2689 }
2690
2691 operands[2] = gen_reg_rtx (SImode);
2692 }")
2693
2694 (define_insn "negdi2_internal"
2695 [(set (match_operand:DI 0 "register_operand" "=d")
2696 (neg:DI (match_operand:DI 1 "register_operand" "d")))
2697 (clobber (match_operand:SI 2 "register_operand" "=d"))]
2698 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2699 "*
2700 {
2701 operands[3] = const0_rtx;
2702 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
2703 }"
2704 [(set_attr "type" "darith")
2705 (set_attr "mode" "DI")
2706 (set_attr "length" "4")])
2707
2708 (define_insn "negdi2_internal_2"
2709 [(set (match_operand:DI 0 "register_operand" "=d")
2710 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
2711 "TARGET_64BIT && !TARGET_MIPS16"
2712 "*
2713 {
2714 operands[2] = const0_rtx;
2715 return \"dsubu\\t%0,%z2,%1\";
2716 }"
2717 [(set_attr "type" "arith")
2718 (set_attr "mode" "DI")
2719 (set_attr "length" "1")])
2720
2721 (define_insn "negdf2"
2722 [(set (match_operand:DF 0 "register_operand" "=f")
2723 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2724 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2725 "neg.d\\t%0,%1"
2726 [(set_attr "type" "fneg")
2727 (set_attr "mode" "DF")
2728 (set_attr "length" "1")])
2729
2730 (define_insn "negsf2"
2731 [(set (match_operand:SF 0 "register_operand" "=f")
2732 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2733 "TARGET_HARD_FLOAT"
2734 "neg.s\\t%0,%1"
2735 [(set_attr "type" "fneg")
2736 (set_attr "mode" "SF")
2737 (set_attr "length" "1")])
2738
2739 (define_insn "one_cmplsi2"
2740 [(set (match_operand:SI 0 "register_operand" "=d")
2741 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2742 ""
2743 "*
2744 {
2745 if (TARGET_MIPS16)
2746 return \"not\\t%0,%1\";
2747 operands[2] = const0_rtx;
2748 return \"nor\\t%0,%z2,%1\";
2749 }"
2750 [(set_attr "type" "arith")
2751 (set_attr "mode" "SI")
2752 (set_attr "length" "1")])
2753
2754 (define_insn "one_cmpldi2"
2755 [(set (match_operand:DI 0 "register_operand" "=d")
2756 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
2757 ""
2758 "*
2759 {
2760 if (TARGET_MIPS16)
2761 {
2762 if (TARGET_64BIT)
2763 return \"not\\t%0,%1\";
2764 return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
2765 }
2766 operands[2] = const0_rtx;
2767 if (TARGET_64BIT)
2768 return \"nor\\t%0,%z2,%1\";
2769 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
2770 }"
2771 [(set_attr "type" "darith")
2772 (set_attr "mode" "DI")
2773 (set (attr "length")
2774 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2775 (const_int 1)
2776 (const_int 2)))])
2777
2778 (define_split
2779 [(set (match_operand:DI 0 "register_operand" "")
2780 (not:DI (match_operand:DI 1 "register_operand" "")))]
2781 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2782 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2783 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2784
2785 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
2786 (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
2787 "")
2788
2789 \f
2790 ;;
2791 ;; ....................
2792 ;;
2793 ;; LOGICAL
2794 ;;
2795 ;; ....................
2796 ;;
2797
2798 ;; Many of these instructions uses trivial define_expands, because we
2799 ;; want to use a different set of constraints when TARGET_MIPS16.
2800
2801 (define_expand "andsi3"
2802 [(set (match_operand:SI 0 "register_operand" "=d,d")
2803 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2804 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2805 ""
2806 "
2807 {
2808 if (TARGET_MIPS16)
2809 operands[2] = force_reg (SImode, operands[2]);
2810 }")
2811
2812 (define_insn ""
2813 [(set (match_operand:SI 0 "register_operand" "=d,d")
2814 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2815 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2816 "!TARGET_MIPS16"
2817 "@
2818 and\\t%0,%1,%2
2819 andi\\t%0,%1,%x2"
2820 [(set_attr "type" "arith")
2821 (set_attr "mode" "SI")
2822 (set_attr "length" "1")])
2823
2824 (define_insn ""
2825 [(set (match_operand:SI 0 "register_operand" "=d")
2826 (and:SI (match_operand:SI 1 "register_operand" "%0")
2827 (match_operand:SI 2 "register_operand" "d")))]
2828 "TARGET_MIPS16"
2829 "and\\t%0,%2"
2830 [(set_attr "type" "arith")
2831 (set_attr "mode" "SI")
2832 (set_attr "length" "1")])
2833
2834 (define_expand "anddi3"
2835 [(set (match_operand:DI 0 "register_operand" "=d")
2836 (and:DI (match_operand:DI 1 "se_register_operand" "d")
2837 (match_operand:DI 2 "se_register_operand" "d")))]
2838 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2839 "
2840 {
2841 if (TARGET_MIPS16)
2842 operands[2] = force_reg (DImode, operands[2]);
2843 }")
2844
2845 (define_insn ""
2846 [(set (match_operand:DI 0 "register_operand" "=d")
2847 (and:DI (match_operand:DI 1 "se_register_operand" "d")
2848 (match_operand:DI 2 "se_register_operand" "d")))]
2849 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2850 "*
2851 {
2852 if (TARGET_64BIT)
2853 return \"and\\t%0,%1,%2\";
2854 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
2855 }"
2856 [(set_attr "type" "darith")
2857 (set_attr "mode" "DI")
2858 (set (attr "length")
2859 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2860 (const_int 1)
2861 (const_int 2)))])
2862
2863 (define_insn ""
2864 [(set (match_operand:DI 0 "register_operand" "=d")
2865 (and:DI (match_operand:DI 1 "se_register_operand" "0")
2866 (match_operand:DI 2 "se_register_operand" "d")))]
2867 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
2868 "*
2869 {
2870 if (TARGET_64BIT)
2871 return \"and\\t%0,%2\";
2872 return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
2873 }"
2874 [(set_attr "type" "darith")
2875 (set_attr "mode" "DI")
2876 (set (attr "length")
2877 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2878 (const_int 1)
2879 (const_int 2)))])
2880
2881 (define_split
2882 [(set (match_operand:DI 0 "register_operand" "")
2883 (and:DI (match_operand:DI 1 "register_operand" "")
2884 (match_operand:DI 2 "register_operand" "")))]
2885 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2886 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2887 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2888 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2889
2890 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2891 (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2892 "")
2893
2894 (define_insn "anddi3_internal1"
2895 [(set (match_operand:DI 0 "register_operand" "=d,d")
2896 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
2897 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2898 "TARGET_64BIT && !TARGET_MIPS16"
2899 "@
2900 and\\t%0,%1,%2
2901 andi\\t%0,%1,%x2"
2902 [(set_attr "type" "arith")
2903 (set_attr "mode" "DI")
2904 (set_attr "length" "1")])
2905
2906 (define_expand "iorsi3"
2907 [(set (match_operand:SI 0 "register_operand" "=d,d")
2908 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2909 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2910 ""
2911 "
2912 {
2913 if (TARGET_MIPS16)
2914 operands[2] = force_reg (SImode, operands[2]);
2915 }")
2916
2917 (define_insn ""
2918 [(set (match_operand:SI 0 "register_operand" "=d,d")
2919 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2920 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2921 "!TARGET_MIPS16"
2922 "@
2923 or\\t%0,%1,%2
2924 ori\\t%0,%1,%x2"
2925 [(set_attr "type" "arith")
2926 (set_attr "mode" "SI")
2927 (set_attr "length" "1")])
2928
2929 (define_insn ""
2930 [(set (match_operand:SI 0 "register_operand" "=d")
2931 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2932 (match_operand:SI 2 "register_operand" "d")))]
2933 "TARGET_MIPS16"
2934 "or\\t%0,%2"
2935 [(set_attr "type" "arith")
2936 (set_attr "mode" "SI")
2937 (set_attr "length" "1")])
2938
2939 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
2940 ;;; TARGET_64BIT
2941
2942 (define_expand "iordi3"
2943 [(set (match_operand:DI 0 "register_operand" "=d")
2944 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2945 (match_operand:DI 2 "se_register_operand" "d")))]
2946 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2947 "")
2948
2949 (define_insn ""
2950 [(set (match_operand:DI 0 "register_operand" "=d")
2951 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2952 (match_operand:DI 2 "se_register_operand" "d")))]
2953 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2954 "*
2955 {
2956 if (TARGET_64BIT)
2957 return \"or\\t%0,%1,%2\";
2958 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
2959 }"
2960 [(set_attr "type" "darith")
2961 (set_attr "mode" "DI")
2962 (set (attr "length")
2963 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2964 (const_int 1)
2965 (const_int 2)))])
2966
2967 (define_insn ""
2968 [(set (match_operand:DI 0 "register_operand" "=d")
2969 (ior:DI (match_operand:DI 1 "se_register_operand" "0")
2970 (match_operand:DI 2 "se_register_operand" "d")))]
2971 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
2972 "*
2973 {
2974 if (TARGET_64BIT)
2975 return \"or\\t%0,%2\";
2976 return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
2977 }"
2978 [(set_attr "type" "darith")
2979 (set_attr "mode" "DI")
2980 (set (attr "length")
2981 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2982 (const_int 1)
2983 (const_int 2)))])
2984
2985 (define_split
2986 [(set (match_operand:DI 0 "register_operand" "")
2987 (ior:DI (match_operand:DI 1 "register_operand" "")
2988 (match_operand:DI 2 "register_operand" "")))]
2989 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2990 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2991 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2992 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2993
2994 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2995 (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2996 "")
2997
2998 (define_expand "xorsi3"
2999 [(set (match_operand:SI 0 "register_operand" "=d,d")
3000 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3001 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3002 ""
3003 "")
3004
3005 (define_insn ""
3006 [(set (match_operand:SI 0 "register_operand" "=d,d")
3007 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3008 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3009 "!TARGET_MIPS16"
3010 "@
3011 xor\\t%0,%1,%2
3012 xori\\t%0,%1,%x2"
3013 [(set_attr "type" "arith")
3014 (set_attr "mode" "SI")
3015 (set_attr "length" "1")])
3016
3017 (define_insn ""
3018 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3019 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3020 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3021 "TARGET_MIPS16"
3022 "@
3023 xor\\t%0,%2
3024 cmpi\\t%1,%2
3025 cmp\\t%1,%2"
3026 [(set_attr "type" "arith")
3027 (set_attr "mode" "SI")
3028 (set_attr_alternative "length"
3029 [(const_int 1)
3030 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3031 (const_int 1)
3032 (const_int 2))
3033 (const_int 1)])])
3034
3035 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3036 ;; the following xordi3_internal pattern.
3037 (define_expand "xordi3"
3038 [(set (match_operand:DI 0 "register_operand" "=d")
3039 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3040 (match_operand:DI 2 "se_register_operand" "d")))]
3041 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3042 "")
3043
3044 (define_insn ""
3045 [(set (match_operand:DI 0 "register_operand" "=d")
3046 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3047 (match_operand:DI 2 "se_register_operand" "d")))]
3048 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3049 "*
3050 {
3051 if (TARGET_64BIT)
3052 return \"xor\\t%0,%1,%2\";
3053 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3054 }"
3055 [(set_attr "type" "darith")
3056 (set_attr "mode" "DI")
3057 (set (attr "length")
3058 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3059 (const_int 1)
3060 (const_int 2)))])
3061
3062 (define_insn ""
3063 [(set (match_operand:DI 0 "register_operand" "=d")
3064 (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3065 (match_operand:DI 2 "se_register_operand" "d")))]
3066 "!TARGET_64BIT && TARGET_MIPS16"
3067 "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3068 [(set_attr "type" "darith")
3069 (set_attr "mode" "DI")
3070 (set_attr "length" "2")])
3071
3072 (define_insn ""
3073 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3074 (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3075 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3076 "TARGET_64BIT && TARGET_MIPS16"
3077 "@
3078 xor\\t%0,%2
3079 cmpi\\t%1,%2
3080 cmp\\t%1,%2"
3081 [(set_attr "type" "arith")
3082 (set_attr "mode" "DI")
3083 (set_attr_alternative "length"
3084 [(const_int 1)
3085 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3086 (const_int 1)
3087 (const_int 2))
3088 (const_int 1)])])
3089
3090 (define_split
3091 [(set (match_operand:DI 0 "register_operand" "")
3092 (xor:DI (match_operand:DI 1 "register_operand" "")
3093 (match_operand:DI 2 "register_operand" "")))]
3094 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3095 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3096 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3097 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3098
3099 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3100 (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3101 "")
3102
3103 (define_insn "xordi3_immed"
3104 [(set (match_operand:DI 0 "register_operand" "=d")
3105 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3106 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3107 "TARGET_64BIT && !TARGET_MIPS16"
3108 "xori\\t%0,%1,%x2"
3109 [(set_attr "type" "arith")
3110 (set_attr "mode" "DI")
3111 (set_attr "length" "1")])
3112
3113 (define_insn "*norsi3"
3114 [(set (match_operand:SI 0 "register_operand" "=d")
3115 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3116 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3117 "!TARGET_MIPS16"
3118 "nor\\t%0,%z1,%z2"
3119 [(set_attr "type" "arith")
3120 (set_attr "mode" "SI")
3121 (set_attr "length" "1")])
3122
3123 (define_insn "*nordi3"
3124 [(set (match_operand:DI 0 "register_operand" "=d")
3125 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3126 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3127 "!TARGET_MIPS16"
3128 "*
3129 {
3130 if (TARGET_64BIT)
3131 return \"nor\\t%0,%z1,%z2\";
3132 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3133 }"
3134 [(set_attr "type" "darith")
3135 (set_attr "mode" "DI")
3136 (set (attr "length")
3137 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3138 (const_int 1)
3139 (const_int 2)))])
3140
3141 (define_split
3142 [(set (match_operand:DI 0 "register_operand" "")
3143 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3144 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3145 "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3146 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3147 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3148 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3149
3150 [(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))))
3151 (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))))]
3152 "")
3153 \f
3154 ;;
3155 ;; ....................
3156 ;;
3157 ;; TRUNCATION
3158 ;;
3159 ;; ....................
3160
3161 (define_insn "truncdfsf2"
3162 [(set (match_operand:SF 0 "register_operand" "=f")
3163 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3164 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3165 "cvt.s.d\\t%0,%1"
3166 [(set_attr "type" "fcvt")
3167 (set_attr "mode" "SF")
3168 (set_attr "length" "1")])
3169
3170 (define_insn "truncdisi2"
3171 [(set (match_operand:SI 0 "register_operand" "=d")
3172 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3173 "TARGET_64BIT"
3174 "*
3175 {
3176 if (TARGET_MIPS16)
3177 return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3178 return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3179 }"
3180 [(set_attr "type" "darith")
3181 (set_attr "mode" "SI")
3182 (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3183 (const_int 2)
3184 (const_int 4)))])
3185
3186 (define_insn "truncdihi2"
3187 [(set (match_operand:HI 0 "register_operand" "=d")
3188 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3189 "TARGET_64BIT && !TARGET_MIPS16"
3190 "andi\\t%0,%1,0xffff"
3191 [(set_attr "type" "darith")
3192 (set_attr "mode" "HI")
3193 (set_attr "length" "1")])
3194
3195 (define_insn "truncdiqi2"
3196 [(set (match_operand:QI 0 "register_operand" "=d")
3197 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3198 "TARGET_64BIT && !TARGET_MIPS16"
3199 "andi\\t%0,%1,0x00ff"
3200 [(set_attr "type" "darith")
3201 (set_attr "mode" "QI")
3202 (set_attr "length" "1")])
3203
3204 ;; Combiner patterns to optimize shift/truncate combinations.
3205 (define_insn ""
3206 [(set (match_operand:SI 0 "register_operand" "=d")
3207 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3208 (match_operand:DI 2 "small_int" "I"))))]
3209 "TARGET_64BIT && !TARGET_MIPS16"
3210 "*
3211 {
3212 int shift_amt = INTVAL (operands[2]) & 0x3f;
3213
3214 if (shift_amt < 32)
3215 {
3216 operands[2] = GEN_INT (32 - shift_amt);
3217 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3218 }
3219 else
3220 {
3221 operands[2] = GEN_INT (shift_amt);
3222 return \"dsra\\t%0,%1,%2\";
3223 }
3224 }"
3225 [(set_attr "type" "darith")
3226 (set_attr "mode" "SI")
3227 (set_attr "length" "2")])
3228
3229 (define_insn ""
3230 [(set (match_operand:SI 0 "register_operand" "=d")
3231 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3232 (match_operand:DI 2 "small_int" "I"))))]
3233 "TARGET_64BIT && !TARGET_MIPS16"
3234 "*
3235 {
3236 int shift_amt = INTVAL (operands[2]) & 0x3f;
3237
3238 if (shift_amt < 32)
3239 {
3240 operands[2] = GEN_INT (32 - shift_amt);
3241 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3242 }
3243 else if (shift_amt == 32)
3244 return \"dsra\\t%0,%1,32\";
3245 else
3246 {
3247 operands[2] = GEN_INT (shift_amt);
3248 return \"dsrl\\t%0,%1,%2\";
3249 }
3250 }"
3251 [(set_attr "type" "darith")
3252 (set_attr "mode" "SI")
3253 (set_attr "length" "2")])
3254
3255 (define_insn ""
3256 [(set (match_operand:SI 0 "register_operand" "=d")
3257 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3258 (match_operand:DI 2 "small_int" "I"))))]
3259 "TARGET_64BIT"
3260 "*
3261 {
3262 int shift_amt = INTVAL (operands[2]) & 0x3f;
3263
3264 if (shift_amt < 32)
3265 {
3266 operands[2] = GEN_INT (32 + shift_amt);
3267 if (TARGET_MIPS16)
3268 return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3269 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3270 }
3271 else
3272 return \"move\\t%0,%.\";
3273 }"
3274 [(set_attr "type" "darith")
3275 (set_attr "mode" "SI")
3276 (set_attr "length" "2")])
3277
3278 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3279
3280 (define_insn ""
3281 [(set (match_operand:SI 0 "register_operand" "=d")
3282 (zero_extend:SI (truncate:HI
3283 (match_operand:DI 1 "se_register_operand" "d"))))]
3284 "TARGET_64BIT && !TARGET_MIPS16"
3285 "andi\\t%0,%1,0xffff"
3286 [(set_attr "type" "darith")
3287 (set_attr "mode" "SI")
3288 (set_attr "length" "1")])
3289
3290 (define_insn ""
3291 [(set (match_operand:SI 0 "register_operand" "=d")
3292 (zero_extend:SI (truncate:QI
3293 (match_operand:DI 1 "se_register_operand" "d"))))]
3294 "TARGET_64BIT && !TARGET_MIPS16"
3295 "andi\\t%0,%1,0xff"
3296 [(set_attr "type" "darith")
3297 (set_attr "mode" "SI")
3298 (set_attr "length" "1")])
3299
3300 (define_insn ""
3301 [(set (match_operand:HI 0 "register_operand" "=d")
3302 (zero_extend:HI (truncate:QI
3303 (match_operand:DI 1 "se_register_operand" "d"))))]
3304 "TARGET_64BIT && !TARGET_MIPS16"
3305 "andi\\t%0,%1,0xff"
3306 [(set_attr "type" "darith")
3307 (set_attr "mode" "HI")
3308 (set_attr "length" "1")])
3309 \f
3310 ;;
3311 ;; ....................
3312 ;;
3313 ;; ZERO EXTENSION
3314 ;;
3315 ;; ....................
3316
3317 ;; Extension insns.
3318 ;; Those for integer source operand are ordered widest source type first.
3319
3320 (define_expand "zero_extendsidi2"
3321 [(set (match_operand:DI 0 "register_operand" "")
3322 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3323 "TARGET_64BIT"
3324 "
3325 {
3326 if (optimize && GET_CODE (operands[1]) == MEM)
3327 operands[1] = force_not_mem (operands[1]);
3328
3329 if (GET_CODE (operands[1]) != MEM)
3330 {
3331 rtx op1 = gen_lowpart (DImode, operands[1]);
3332 rtx temp = gen_reg_rtx (DImode);
3333 rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
3334
3335 emit_insn (gen_ashldi3 (temp, op1, shift));
3336 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3337 DONE;
3338 }
3339 }")
3340
3341 (define_insn "zero_extendsidi2_internal"
3342 [(set (match_operand:DI 0 "register_operand" "=d,d")
3343 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3344 "TARGET_64BIT"
3345 "* return mips_move_1word (operands, insn, TRUE);"
3346 [(set_attr "type" "load")
3347 (set_attr "mode" "DI")
3348 (set_attr "length" "1,2")])
3349
3350 (define_expand "zero_extendhisi2"
3351 [(set (match_operand:SI 0 "register_operand" "")
3352 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3353 ""
3354 "
3355 {
3356 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3357 {
3358 rtx op = gen_lowpart (SImode, operands[1]);
3359 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3360
3361 emit_insn (gen_andsi3 (operands[0], op, temp));
3362 DONE;
3363 }
3364 }")
3365
3366 (define_insn ""
3367 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3368 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3369 "!TARGET_MIPS16"
3370 "*
3371 {
3372 if (which_alternative == 0)
3373 return \"andi\\t%0,%1,0xffff\";
3374 else
3375 return mips_move_1word (operands, insn, TRUE);
3376 }"
3377 [(set_attr "type" "arith,load,load")
3378 (set_attr "mode" "SI")
3379 (set_attr "length" "1,1,2")])
3380
3381 (define_insn ""
3382 [(set (match_operand:SI 0 "register_operand" "=d,d")
3383 (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3384 "TARGET_MIPS16"
3385 "* return mips_move_1word (operands, insn, TRUE);"
3386 [(set_attr "type" "load,load")
3387 (set_attr "mode" "SI")
3388 (set_attr "length" "1,2")])
3389
3390 (define_expand "zero_extendhidi2"
3391 [(set (match_operand:DI 0 "register_operand" "")
3392 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3393 "TARGET_64BIT"
3394 "
3395 {
3396 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3397 {
3398 rtx op = gen_lowpart (DImode, operands[1]);
3399 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3400
3401 emit_insn (gen_anddi3 (operands[0], op, temp));
3402 DONE;
3403 }
3404 }")
3405
3406 (define_insn ""
3407 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3408 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3409 "TARGET_64BIT && !TARGET_MIPS16"
3410 "*
3411 {
3412 if (which_alternative == 0)
3413 return \"andi\\t%0,%1,0xffff\";
3414 else
3415 return mips_move_1word (operands, insn, TRUE);
3416 }"
3417 [(set_attr "type" "arith,load,load")
3418 (set_attr "mode" "DI")
3419 (set_attr "length" "1,1,2")])
3420
3421 (define_insn ""
3422 [(set (match_operand:DI 0 "register_operand" "=d,d")
3423 (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3424 "TARGET_64BIT && TARGET_MIPS16"
3425 "* return mips_move_1word (operands, insn, TRUE);"
3426 [(set_attr "type" "load,load")
3427 (set_attr "mode" "DI")
3428 (set_attr "length" "1,2")])
3429
3430 (define_expand "zero_extendqihi2"
3431 [(set (match_operand:HI 0 "register_operand" "")
3432 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3433 ""
3434 "
3435 {
3436 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3437 {
3438 rtx op0 = gen_lowpart (SImode, operands[0]);
3439 rtx op1 = gen_lowpart (SImode, operands[1]);
3440 rtx temp = force_reg (SImode, GEN_INT (0xff));
3441
3442 emit_insn (gen_andsi3 (op0, op1, temp));
3443 DONE;
3444 }
3445 }")
3446
3447 (define_insn ""
3448 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3449 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3450 "!TARGET_MIPS16"
3451 "*
3452 {
3453 if (which_alternative == 0)
3454 return \"andi\\t%0,%1,0x00ff\";
3455 else
3456 return mips_move_1word (operands, insn, TRUE);
3457 }"
3458 [(set_attr "type" "arith,load,load")
3459 (set_attr "mode" "HI")
3460 (set_attr "length" "1,1,2")])
3461
3462 (define_insn ""
3463 [(set (match_operand:HI 0 "register_operand" "=d,d")
3464 (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3465 "TARGET_MIPS16"
3466 "* return mips_move_1word (operands, insn, TRUE);"
3467 [(set_attr "type" "load,load")
3468 (set_attr "mode" "HI")
3469 (set_attr "length" "1,2")])
3470
3471 (define_expand "zero_extendqisi2"
3472 [(set (match_operand:SI 0 "register_operand" "")
3473 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3474 ""
3475 "
3476 {
3477 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3478 {
3479 rtx op = gen_lowpart (SImode, operands[1]);
3480 rtx temp = force_reg (SImode, GEN_INT (0xff));
3481
3482 emit_insn (gen_andsi3 (operands[0], op, temp));
3483 DONE;
3484 }
3485 }")
3486
3487 (define_insn ""
3488 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3489 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3490 "!TARGET_MIPS16"
3491 "*
3492 {
3493 if (which_alternative == 0)
3494 return \"andi\\t%0,%1,0x00ff\";
3495 else
3496 return mips_move_1word (operands, insn, TRUE);
3497 }"
3498 [(set_attr "type" "arith,load,load")
3499 (set_attr "mode" "SI")
3500 (set_attr "length" "1,1,2")])
3501
3502 (define_insn ""
3503 [(set (match_operand:SI 0 "register_operand" "=d,d")
3504 (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3505 "TARGET_MIPS16"
3506 "* return mips_move_1word (operands, insn, TRUE);"
3507 [(set_attr "type" "load,load")
3508 (set_attr "mode" "SI")
3509 (set_attr "length" "1,2")])
3510
3511 (define_expand "zero_extendqidi2"
3512 [(set (match_operand:DI 0 "register_operand" "")
3513 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3514 "TARGET_64BIT"
3515 "
3516 {
3517 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3518 {
3519 rtx op = gen_lowpart (DImode, operands[1]);
3520 rtx temp = force_reg (DImode, GEN_INT (0xff));
3521
3522 emit_insn (gen_anddi3 (operands[0], op, temp));
3523 DONE;
3524 }
3525 }")
3526
3527 (define_insn ""
3528 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3529 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3530 "TARGET_64BIT && !TARGET_MIPS16"
3531 "*
3532 {
3533 if (which_alternative == 0)
3534 return \"andi\\t%0,%1,0x00ff\";
3535 else
3536 return mips_move_1word (operands, insn, TRUE);
3537 }"
3538 [(set_attr "type" "arith,load,load")
3539 (set_attr "mode" "DI")
3540 (set_attr "length" "1,1,2")])
3541
3542 ;; These can be created when a paradoxical subreg operand with an implicit
3543 ;; sign_extend operator is reloaded. Because of the subreg, this is really
3544 ;; a zero extend.
3545 ;; ??? It might be possible to eliminate the need for these patterns by adding
3546 ;; more support to reload for implicit sign_extend operators.
3547 (define_insn "*paradoxical_extendhidi2"
3548 [(set (match_operand:DI 0 "register_operand" "=d,d")
3549 (sign_extend:DI
3550 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
3551 "TARGET_64BIT"
3552 "*
3553 {
3554 return mips_move_1word (operands, insn, TRUE);
3555 }"
3556 [(set_attr "type" "load,load")
3557 (set_attr "mode" "DI")
3558 (set_attr "length" "1,2")])
3559
3560 (define_insn ""
3561 [(set (match_operand:DI 0 "register_operand" "=d,d")
3562 (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3563 "TARGET_64BIT && TARGET_MIPS16"
3564 "* return mips_move_1word (operands, insn, TRUE);"
3565 [(set_attr "type" "load,load")
3566 (set_attr "mode" "DI")
3567 (set_attr "length" "1,2")])
3568 \f
3569 ;;
3570 ;; ....................
3571 ;;
3572 ;; SIGN EXTENSION
3573 ;;
3574 ;; ....................
3575
3576 ;; Extension insns.
3577 ;; Those for integer source operand are ordered widest source type first.
3578
3579 ;; In 64 bit mode, 32 bit values in general registers are always
3580 ;; correctly sign extended. That means that if the target is a
3581 ;; general register, we can sign extend from SImode to DImode just by
3582 ;; doing a move.
3583
3584 (define_insn "extendsidi2"
3585 [(set (match_operand:DI 0 "register_operand" "=d,*d,d,d")
3586 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,*x,R,m")))]
3587 "TARGET_64BIT"
3588 "* return mips_move_1word (operands, insn, FALSE);"
3589 [(set_attr "type" "move,hilo,load,load")
3590 (set_attr "mode" "DI")
3591 (set_attr "length" "1,1,1,2")])
3592
3593 ;; These patterns originally accepted general_operands, however, slightly
3594 ;; better code is generated by only accepting register_operands, and then
3595 ;; letting combine generate the lh and lb insns.
3596
3597 (define_expand "extendhidi2"
3598 [(set (match_operand:DI 0 "register_operand" "")
3599 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3600 "TARGET_64BIT"
3601 "
3602 {
3603 if (optimize && GET_CODE (operands[1]) == MEM)
3604 operands[1] = force_not_mem (operands[1]);
3605
3606 if (GET_CODE (operands[1]) != MEM)
3607 {
3608 rtx op1 = gen_lowpart (DImode, operands[1]);
3609 rtx temp = gen_reg_rtx (DImode);
3610 rtx shift = gen_rtx (CONST_INT, VOIDmode, 48);
3611
3612 emit_insn (gen_ashldi3 (temp, op1, shift));
3613 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3614 DONE;
3615 }
3616 }")
3617
3618 (define_insn "extendhidi2_internal"
3619 [(set (match_operand:DI 0 "register_operand" "=d,d")
3620 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3621 "TARGET_64BIT"
3622 "* return mips_move_1word (operands, insn, FALSE);"
3623 [(set_attr "type" "load")
3624 (set_attr "mode" "DI")
3625 (set_attr "length" "1,2")])
3626
3627 (define_expand "extendhisi2"
3628 [(set (match_operand:SI 0 "register_operand" "")
3629 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3630 ""
3631 "
3632 {
3633 if (optimize && GET_CODE (operands[1]) == MEM)
3634 operands[1] = force_not_mem (operands[1]);
3635
3636 if (GET_CODE (operands[1]) != MEM)
3637 {
3638 rtx op1 = gen_lowpart (SImode, operands[1]);
3639 rtx temp = gen_reg_rtx (SImode);
3640 rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
3641
3642 emit_insn (gen_ashlsi3 (temp, op1, shift));
3643 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3644 DONE;
3645 }
3646 }")
3647
3648 (define_insn "extendhisi2_internal"
3649 [(set (match_operand:SI 0 "register_operand" "=d,d")
3650 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3651 ""
3652 "* return mips_move_1word (operands, insn, FALSE);"
3653 [(set_attr "type" "load")
3654 (set_attr "mode" "SI")
3655 (set_attr "length" "1,2")])
3656
3657 (define_expand "extendqihi2"
3658 [(set (match_operand:HI 0 "register_operand" "")
3659 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3660 ""
3661 "
3662 {
3663 if (optimize && GET_CODE (operands[1]) == MEM)
3664 operands[1] = force_not_mem (operands[1]);
3665
3666 if (GET_CODE (operands[1]) != MEM)
3667 {
3668 rtx op0 = gen_lowpart (SImode, operands[0]);
3669 rtx op1 = gen_lowpart (SImode, operands[1]);
3670 rtx temp = gen_reg_rtx (SImode);
3671 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
3672
3673 emit_insn (gen_ashlsi3 (temp, op1, shift));
3674 emit_insn (gen_ashrsi3 (op0, temp, shift));
3675 DONE;
3676 }
3677 }")
3678
3679 (define_insn "extendqihi2_internal"
3680 [(set (match_operand:HI 0 "register_operand" "=d,d")
3681 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3682 ""
3683 "* return mips_move_1word (operands, insn, FALSE);"
3684 [(set_attr "type" "load")
3685 (set_attr "mode" "SI")
3686 (set_attr "length" "1,2")])
3687
3688
3689 (define_expand "extendqisi2"
3690 [(set (match_operand:SI 0 "register_operand" "")
3691 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3692 ""
3693 "
3694 {
3695 if (optimize && GET_CODE (operands[1]) == MEM)
3696 operands[1] = force_not_mem (operands[1]);
3697
3698 if (GET_CODE (operands[1]) != MEM)
3699 {
3700 rtx op1 = gen_lowpart (SImode, operands[1]);
3701 rtx temp = gen_reg_rtx (SImode);
3702 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
3703
3704 emit_insn (gen_ashlsi3 (temp, op1, shift));
3705 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3706 DONE;
3707 }
3708 }")
3709
3710 (define_insn "extendqisi2_insn"
3711 [(set (match_operand:SI 0 "register_operand" "=d,d")
3712 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3713 ""
3714 "* return mips_move_1word (operands, insn, FALSE);"
3715 [(set_attr "type" "load")
3716 (set_attr "mode" "SI")
3717 (set_attr "length" "1,2")])
3718
3719 (define_expand "extendqidi2"
3720 [(set (match_operand:DI 0 "register_operand" "")
3721 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3722 "TARGET_64BIT"
3723 "
3724 {
3725 if (optimize && GET_CODE (operands[1]) == MEM)
3726 operands[1] = force_not_mem (operands[1]);
3727
3728 if (GET_CODE (operands[1]) != MEM)
3729 {
3730 rtx op1 = gen_lowpart (DImode, operands[1]);
3731 rtx temp = gen_reg_rtx (DImode);
3732 rtx shift = gen_rtx (CONST_INT, VOIDmode, 56);
3733
3734 emit_insn (gen_ashldi3 (temp, op1, shift));
3735 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3736 DONE;
3737 }
3738 }")
3739
3740 (define_insn "extendqidi2_insn"
3741 [(set (match_operand:DI 0 "register_operand" "=d,d")
3742 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3743 "TARGET_64BIT"
3744 "* return mips_move_1word (operands, insn, FALSE);"
3745 [(set_attr "type" "load")
3746 (set_attr "mode" "DI")
3747 (set_attr "length" "1,2")])
3748
3749
3750 (define_insn "extendsfdf2"
3751 [(set (match_operand:DF 0 "register_operand" "=f")
3752 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3753 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3754 "cvt.d.s\\t%0,%1"
3755 [(set_attr "type" "fcvt")
3756 (set_attr "mode" "DF")
3757 (set_attr "length" "1")])
3758
3759 \f
3760
3761 ;;
3762 ;; ....................
3763 ;;
3764 ;; CONVERSIONS
3765 ;;
3766 ;; ....................
3767
3768 ;; The SImode scratch register can not be shared with address regs used for
3769 ;; operand zero, because then the address in the move instruction will be
3770 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
3771
3772 ;; We need the ?X in alternative 1 so that it will be choosen only if the
3773 ;; destination is a floating point register. Otherwise, alternative 1 can
3774 ;; have lower cost than alternative 0 (because there is one less loser), and
3775 ;; can be choosen when it won't work (because integral reloads into FP
3776 ;; registers are not supported).
3777
3778 (define_insn "fix_truncdfsi2"
3779 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
3780 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
3781 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
3782 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
3783 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3784 "*
3785 {
3786 rtx xoperands[10];
3787
3788 if (which_alternative == 1)
3789 return \"trunc.w.d %0,%1,%2\";
3790
3791 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
3792
3793 xoperands[0] = operands[0];
3794 xoperands[1] = operands[3];
3795 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
3796 return \"\";
3797 }"
3798 [(set_attr "type" "fcvt")
3799 (set_attr "mode" "DF")
3800 (set_attr "length" "11,9,10,11")])
3801
3802
3803 (define_insn "fix_truncsfsi2"
3804 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
3805 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
3806 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
3807 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
3808 "TARGET_HARD_FLOAT"
3809 "*
3810 {
3811 rtx xoperands[10];
3812
3813 if (which_alternative == 1)
3814 return \"trunc.w.s %0,%1,%2\";
3815
3816 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
3817
3818 xoperands[0] = operands[0];
3819 xoperands[1] = operands[3];
3820 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
3821 return \"\";
3822 }"
3823 [(set_attr "type" "fcvt")
3824 (set_attr "mode" "SF")
3825 (set_attr "length" "11,9,10,11")])
3826
3827
3828 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
3829 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
3830 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
3831
3832 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
3833 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
3834
3835 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
3836
3837 (define_insn "fix_truncdfdi2"
3838 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
3839 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
3840 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
3841 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3842 "*
3843 {
3844 rtx xoperands[10];
3845
3846 if (which_alternative == 1)
3847 return \"trunc.l.d %0,%1\";
3848
3849 output_asm_insn (\"trunc.l.d %2,%1\", operands);
3850
3851 xoperands[0] = operands[0];
3852 xoperands[1] = operands[2];
3853 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
3854 return \"\";
3855 }"
3856 [(set_attr "type" "fcvt")
3857 (set_attr "mode" "DF")
3858 (set_attr "length" "2,1,2,3")])
3859
3860
3861 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
3862 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
3863 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
3864 (define_insn "fix_truncsfdi2"
3865 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
3866 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
3867 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
3868 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3869 "*
3870 {
3871 rtx xoperands[10];
3872
3873 if (which_alternative == 1)
3874 return \"trunc.l.s %0,%1\";
3875
3876 output_asm_insn (\"trunc.l.s %2,%1\", operands);
3877
3878 xoperands[0] = operands[0];
3879 xoperands[1] = operands[2];
3880 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
3881 return \"\";
3882 }"
3883 [(set_attr "type" "fcvt")
3884 (set_attr "mode" "SF")
3885 (set_attr "length" "2,1,2,3")])
3886
3887
3888 (define_insn "floatsidf2"
3889 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
3890 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
3891 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3892 "*
3893 {
3894 dslots_load_total++;
3895 if (GET_CODE (operands[1]) == MEM)
3896 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
3897
3898 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
3899 }"
3900 [(set_attr "type" "fcvt")
3901 (set_attr "mode" "DF")
3902 (set_attr "length" "3,4,3")])
3903
3904
3905 (define_insn "floatdidf2"
3906 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
3907 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
3908 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3909 "*
3910 {
3911 dslots_load_total++;
3912 if (GET_CODE (operands[1]) == MEM)
3913 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
3914
3915 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
3916 }"
3917 [(set_attr "type" "fcvt")
3918 (set_attr "mode" "DF")
3919 (set_attr "length" "3,4,3")])
3920
3921
3922 (define_insn "floatsisf2"
3923 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
3924 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
3925 "TARGET_HARD_FLOAT"
3926 "*
3927 {
3928 dslots_load_total++;
3929 if (GET_CODE (operands[1]) == MEM)
3930 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
3931
3932 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
3933 }"
3934 [(set_attr "type" "fcvt")
3935 (set_attr "mode" "SF")
3936 (set_attr "length" "3,4,3")])
3937
3938
3939 (define_insn "floatdisf2"
3940 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
3941 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
3942 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3943 "*
3944 {
3945 dslots_load_total++;
3946 if (GET_CODE (operands[1]) == MEM)
3947 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
3948
3949 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
3950 }"
3951 [(set_attr "type" "fcvt")
3952 (set_attr "mode" "SF")
3953 (set_attr "length" "3,4,3")])
3954
3955
3956 (define_expand "fixuns_truncdfsi2"
3957 [(set (match_operand:SI 0 "register_operand" "")
3958 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
3959 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3960 "
3961 {
3962 rtx reg1 = gen_reg_rtx (DFmode);
3963 rtx reg2 = gen_reg_rtx (DFmode);
3964 rtx reg3 = gen_reg_rtx (SImode);
3965 rtx label1 = gen_label_rtx ();
3966 rtx label2 = gen_label_rtx ();
3967 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
3968
3969 if (reg1) /* turn off complaints about unreached code */
3970 {
3971 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
3972 do_pending_stack_adjust ();
3973
3974 emit_insn (gen_cmpdf (operands[1], reg1));
3975 emit_jump_insn (gen_bge (label1));
3976
3977 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3978 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3979 gen_rtx (LABEL_REF, VOIDmode, label2)));
3980 emit_barrier ();
3981
3982 emit_label (label1);
3983 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
3984 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3985
3986 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3987 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3988
3989 emit_label (label2);
3990
3991 /* allow REG_NOTES to be set on last insn (labels don't have enough
3992 fields, and can't be used for REG_NOTES anyway). */
3993 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3994 DONE;
3995 }
3996 }")
3997
3998
3999 (define_expand "fixuns_truncdfdi2"
4000 [(set (match_operand:DI 0 "register_operand" "")
4001 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4002 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4003 "
4004 {
4005 rtx reg1 = gen_reg_rtx (DFmode);
4006 rtx reg2 = gen_reg_rtx (DFmode);
4007 rtx reg3 = gen_reg_rtx (DImode);
4008 rtx label1 = gen_label_rtx ();
4009 rtx label2 = gen_label_rtx ();
4010 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4011
4012 if (reg1) /* turn off complaints about unreached code */
4013 {
4014 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4015 do_pending_stack_adjust ();
4016
4017 emit_insn (gen_cmpdf (operands[1], reg1));
4018 emit_jump_insn (gen_bge (label1));
4019
4020 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4021 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4022 gen_rtx (LABEL_REF, VOIDmode, label2)));
4023 emit_barrier ();
4024
4025 emit_label (label1);
4026 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4027 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
4028 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4029
4030 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4031 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4032
4033 emit_label (label2);
4034
4035 /* allow REG_NOTES to be set on last insn (labels don't have enough
4036 fields, and can't be used for REG_NOTES anyway). */
4037 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4038 DONE;
4039 }
4040 }")
4041
4042
4043 (define_expand "fixuns_truncsfsi2"
4044 [(set (match_operand:SI 0 "register_operand" "")
4045 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4046 "TARGET_HARD_FLOAT"
4047 "
4048 {
4049 rtx reg1 = gen_reg_rtx (SFmode);
4050 rtx reg2 = gen_reg_rtx (SFmode);
4051 rtx reg3 = gen_reg_rtx (SImode);
4052 rtx label1 = gen_label_rtx ();
4053 rtx label2 = gen_label_rtx ();
4054 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4055
4056 if (reg1) /* turn off complaints about unreached code */
4057 {
4058 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4059 do_pending_stack_adjust ();
4060
4061 emit_insn (gen_cmpsf (operands[1], reg1));
4062 emit_jump_insn (gen_bge (label1));
4063
4064 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4065 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4066 gen_rtx (LABEL_REF, VOIDmode, label2)));
4067 emit_barrier ();
4068
4069 emit_label (label1);
4070 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4071 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
4072
4073 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4074 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4075
4076 emit_label (label2);
4077
4078 /* allow REG_NOTES to be set on last insn (labels don't have enough
4079 fields, and can't be used for REG_NOTES anyway). */
4080 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4081 DONE;
4082 }
4083 }")
4084
4085
4086 (define_expand "fixuns_truncsfdi2"
4087 [(set (match_operand:DI 0 "register_operand" "")
4088 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4089 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4090 "
4091 {
4092 rtx reg1 = gen_reg_rtx (SFmode);
4093 rtx reg2 = gen_reg_rtx (SFmode);
4094 rtx reg3 = gen_reg_rtx (DImode);
4095 rtx label1 = gen_label_rtx ();
4096 rtx label2 = gen_label_rtx ();
4097 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4098
4099 if (reg1) /* turn off complaints about unreached code */
4100 {
4101 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4102 do_pending_stack_adjust ();
4103
4104 emit_insn (gen_cmpsf (operands[1], reg1));
4105 emit_jump_insn (gen_bge (label1));
4106
4107 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4108 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4109 gen_rtx (LABEL_REF, VOIDmode, label2)));
4110 emit_barrier ();
4111
4112 emit_label (label1);
4113 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4114 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
4115 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4116
4117 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4118 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4119
4120 emit_label (label2);
4121
4122 /* allow REG_NOTES to be set on last insn (labels don't have enough
4123 fields, and can't be used for REG_NOTES anyway). */
4124 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4125 DONE;
4126 }
4127 }")
4128
4129 \f
4130 ;;
4131 ;; ....................
4132 ;;
4133 ;; DATA MOVEMENT
4134 ;;
4135 ;; ....................
4136
4137 ;; Bit field extract patterns which use lwl/lwr.
4138
4139 ;; ??? There should be DImode variants for 64 bit code, but the current
4140 ;; bitfield scheme can't handle that. We would need to add new optabs
4141 ;; in order to make that work.
4142
4143 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4144 ;; It isn't clear whether this will give better code.
4145
4146 (define_expand "extv"
4147 [(set (match_operand:SI 0 "register_operand" "")
4148 (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
4149 (match_operand:SI 2 "immediate_operand" "")
4150 (match_operand:SI 3 "immediate_operand" "")))]
4151 "!TARGET_MIPS16"
4152 "
4153 {
4154 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
4155 then fail. */
4156 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
4157 FAIL;
4158
4159 /* This can happen for a 64 bit target, when extracting a value from
4160 a 64 bit union member. extract_bit_field doesn't verify that our
4161 source matches the predicate, so we force it to be a MEM here. */
4162 if (GET_CODE (operands[1]) != MEM)
4163 FAIL;
4164
4165 /* Change the mode to BLKmode for aliasing purposes. */
4166 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4167
4168 /* Otherwise, emit a lwl/lwr pair to load the value. */
4169 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4170 DONE;
4171 }")
4172
4173 (define_expand "extzv"
4174 [(set (match_operand:SI 0 "register_operand" "")
4175 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
4176 (match_operand:SI 2 "immediate_operand" "")
4177 (match_operand:SI 3 "immediate_operand" "")))]
4178 "!TARGET_MIPS16"
4179 "
4180 {
4181 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
4182 then fail. */
4183 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
4184 FAIL;
4185
4186 /* This can happen for a 64 bit target, when extracting a value from
4187 a 64 bit union member. extract_bit_field doesn't verify that our
4188 source matches the predicate, so we force it to be a MEM here. */
4189 if (GET_CODE (operands[1]) != MEM)
4190 FAIL;
4191
4192 /* Change the mode to BLKmode for aliasing purposes. */
4193 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4194
4195 /* Otherwise, emit a lwl/lwr pair to load the value. */
4196 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4197 DONE;
4198 }")
4199
4200 (define_expand "insv"
4201 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
4202 (match_operand:SI 1 "immediate_operand" "")
4203 (match_operand:SI 2 "immediate_operand" ""))
4204 (match_operand:SI 3 "register_operand" ""))]
4205 "!TARGET_MIPS16"
4206 "
4207 {
4208 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
4209 then fail. */
4210 if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
4211 FAIL;
4212
4213 /* This can happen for a 64 bit target, when storing into a 32 bit union
4214 member. store_bit_field doesn't verify that our target matches the
4215 predicate, so we force it to be a MEM here. */
4216 if (GET_CODE (operands[0]) != MEM)
4217 FAIL;
4218
4219 /* Change the mode to BLKmode for aliasing purposes. */
4220 operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
4221
4222 /* Otherwise, emit a swl/swr pair to load the value. */
4223 emit_insn (gen_movsi_usw (operands[0], operands[3]));
4224 DONE;
4225 }")
4226
4227 ;; unaligned word moves generated by the bit field patterns
4228
4229 (define_insn "movsi_ulw"
4230 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4231 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4232 "!TARGET_MIPS16"
4233 "*
4234 {
4235 rtx offset = const0_rtx;
4236 rtx addr = XEXP (operands[1], 0);
4237 rtx mem_addr = eliminate_constant_term (addr, &offset);
4238 char *ret;
4239
4240 if (TARGET_STATS)
4241 mips_count_memory_refs (operands[1], 2);
4242
4243 /* The stack/frame pointers are always aligned, so we can convert
4244 to the faster lw if we are referencing an aligned stack location. */
4245
4246 if ((INTVAL (offset) & 3) == 0
4247 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4248 ret = \"lw\\t%0,%1\";
4249 else
4250 ret = \"ulw\\t%0,%1\";
4251
4252 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4253 }"
4254 [(set_attr "type" "load,load")
4255 (set_attr "mode" "SI")
4256 (set_attr "length" "2,4")])
4257
4258 (define_insn "movsi_usw"
4259 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4260 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4261 "!TARGET_MIPS16"
4262 "*
4263 {
4264 rtx offset = const0_rtx;
4265 rtx addr = XEXP (operands[0], 0);
4266 rtx mem_addr = eliminate_constant_term (addr, &offset);
4267
4268 if (TARGET_STATS)
4269 mips_count_memory_refs (operands[0], 2);
4270
4271 /* The stack/frame pointers are always aligned, so we can convert
4272 to the faster sw if we are referencing an aligned stack location. */
4273
4274 if ((INTVAL (offset) & 3) == 0
4275 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4276 return \"sw\\t%1,%0\";
4277
4278 return \"usw\\t%z1,%0\";
4279 }"
4280 [(set_attr "type" "store")
4281 (set_attr "mode" "SI")
4282 (set_attr "length" "2,4")])
4283
4284 ;; These two patterns support loading addresses with two instructions instead
4285 ;; of using the macro instruction la.
4286
4287 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4288 ;; unnecessary.
4289
4290 (define_insn "high"
4291 [(set (match_operand:SI 0 "register_operand" "=r")
4292 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4293 "mips_split_addresses && !TARGET_MIPS16"
4294 "lui\\t%0,%%hi(%1) # high"
4295 [(set_attr "type" "move")
4296 (set_attr "length" "1")])
4297
4298 (define_insn "low"
4299 [(set (match_operand:SI 0 "register_operand" "=r")
4300 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4301 (match_operand:SI 2 "immediate_operand" "")))]
4302 "mips_split_addresses && !TARGET_MIPS16"
4303 "addiu\\t%0,%1,%%lo(%2) # low"
4304 [(set_attr "type" "arith")
4305 (set_attr "mode" "SI")
4306 (set_attr "length" "1")])
4307
4308 ;; 64-bit integer moves
4309
4310 ;; Unlike most other insns, the move insns can't be split with
4311 ;; different predicates, because register spilling and other parts of
4312 ;; the compiler, have memoized the insn number already.
4313
4314 (define_expand "movdi"
4315 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4316 (match_operand:DI 1 "general_operand" ""))]
4317 ""
4318 "
4319 {
4320 if (mips_split_addresses && mips_check_split (operands[1], DImode))
4321 {
4322 enum machine_mode mode = GET_MODE (operands[0]);
4323 rtx tem = ((reload_in_progress | reload_completed)
4324 ? operands[0] : gen_reg_rtx (mode));
4325
4326 emit_insn (gen_rtx (SET, VOIDmode, tem,
4327 gen_rtx (HIGH, mode, operands[1])));
4328
4329 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4330 }
4331
4332 /* If we are generating embedded PIC code, and we are referring to a
4333 symbol in the .text section, we must use an offset from the start
4334 of the function. */
4335 if (TARGET_EMBEDDED_PIC
4336 && (GET_CODE (operands[1]) == LABEL_REF
4337 || (GET_CODE (operands[1]) == SYMBOL_REF
4338 && ! SYMBOL_REF_FLAG (operands[1]))))
4339 {
4340 rtx temp;
4341
4342 temp = embedded_pic_offset (operands[1]);
4343 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4344 force_reg (DImode, temp));
4345 emit_move_insn (operands[0], force_reg (DImode, temp));
4346 DONE;
4347 }
4348
4349 /* If operands[1] is a constant address illegal for pic, then we need to
4350 handle it just like LEGITIMIZE_ADDRESS does. */
4351 if (flag_pic && pic_address_needs_scratch (operands[1]))
4352 {
4353 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4354 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4355
4356 if (! SMALL_INT (temp2))
4357 temp2 = force_reg (DImode, temp2);
4358
4359 emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
4360 DONE;
4361 }
4362
4363 /* On the mips16, we can handle a GP relative reference by adding in
4364 $gp. We need to check the name to see whether this is a string
4365 constant. */
4366 if (TARGET_MIPS16
4367 && register_operand (operands[0], DImode)
4368 && GET_CODE (operands[1]) == SYMBOL_REF
4369 && SYMBOL_REF_FLAG (operands[1]))
4370 {
4371 char *name = XSTR (operands[1], 0);
4372
4373 if (name[0] != '*'
4374 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4375 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4376 {
4377 rtx base_reg;
4378
4379 if (reload_in_progress || reload_completed)
4380 {
4381 /* In movsi we use the constant table here. However, in
4382 this case, we're better off copying $28 into a
4383 register and adding, because the constant table entry
4384 would be 8 bytes. */
4385 base_reg = operands[0];
4386 emit_move_insn (base_reg,
4387 gen_rtx (CONST, DImode,
4388 gen_rtx (REG, DImode,
4389 GP_REG_FIRST + 28)));
4390 }
4391 else
4392 {
4393 base_reg = gen_reg_rtx (Pmode);
4394 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4395 }
4396
4397 emit_move_insn (operands[0],
4398 gen_rtx (PLUS, SImode, base_reg,
4399 mips16_gp_offset (operands[1])));
4400 DONE;
4401 }
4402 }
4403
4404 if ((reload_in_progress | reload_completed) == 0
4405 && !register_operand (operands[0], DImode)
4406 && !register_operand (operands[1], DImode)
4407 && (TARGET_MIPS16
4408 || (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4409 && operands[1] != CONST0_RTX (DImode)))
4410 {
4411 rtx temp = force_reg (DImode, operands[1]);
4412 emit_move_insn (operands[0], temp);
4413 DONE;
4414 }
4415 }")
4416
4417 ;; For mips16, we need a special case to handle storing $31 into
4418 ;; memory, since we don't have a constraint to match $31. This
4419 ;; instruction can be generated by save_restore_insns.
4420
4421 (define_insn ""
4422 [(set (match_operand:DI 0 "memory_operand" "R,m")
4423 (reg:DI 31))]
4424 "TARGET_MIPS16 && TARGET_64BIT"
4425 "*
4426 {
4427 operands[1] = gen_rtx (REG, DImode, 31);
4428 return mips_move_2words (operands, insn);
4429 }"
4430 [(set_attr "type" "store")
4431 (set_attr "mode" "DI")
4432 (set_attr "length" "1,2")])
4433
4434 (define_insn "movdi_internal"
4435 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
4436 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
4437 "!TARGET_64BIT && !TARGET_MIPS16
4438 && (register_operand (operands[0], DImode)
4439 || register_operand (operands[1], DImode)
4440 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4441 || operands[1] == CONST0_RTX (DImode))"
4442 "* return mips_move_2words (operands, insn); "
4443 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo")
4444 (set_attr "mode" "DI")
4445 (set_attr "length" "2,4,2,4,2,4,2,2,2")])
4446
4447 (define_insn ""
4448 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
4449 (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
4450 "!TARGET_64BIT && TARGET_MIPS16
4451 && (register_operand (operands[0], DImode)
4452 || register_operand (operands[1], DImode))"
4453 "* return mips_move_2words (operands, insn);"
4454 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
4455 (set_attr "mode" "DI")
4456 (set_attr "length" "2,2,2,2,3,2,4,2,4,2")])
4457
4458 (define_split
4459 [(set (match_operand:DI 0 "register_operand" "")
4460 (match_operand:DI 1 "register_operand" ""))]
4461 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4462 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4463 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4464
4465 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4466 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4467 "")
4468
4469 (define_insn "movdi_internal2"
4470 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
4471 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
4472 "TARGET_64BIT && !TARGET_MIPS16
4473 && (register_operand (operands[0], DImode)
4474 || se_register_operand (operands[1], DImode)
4475 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4476 || operands[1] == CONST0_RTX (DImode))"
4477 "* return mips_move_2words (operands, insn); "
4478 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
4479 (set_attr "mode" "DI")
4480 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,2")])
4481
4482 (define_insn ""
4483 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
4484 (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
4485 "TARGET_64BIT && TARGET_MIPS16
4486 && (register_operand (operands[0], DImode)
4487 || se_register_operand (operands[1], DImode))"
4488 "* return mips_move_2words (operands, insn);"
4489 [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
4490 (set_attr "mode" "DI")
4491 (set_attr_alternative "length"
4492 [(const_int 1)
4493 (const_int 1)
4494 (const_int 1)
4495 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4496 (const_int 1)
4497 (const_int 2))
4498 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4499 (const_int 2)
4500 (const_int 3))
4501 (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
4502 (const_int 1)
4503 (const_int 2))
4504 (const_int 1)
4505 (const_int 2)
4506 (const_int 1)
4507 (const_int 2)
4508 (const_int 1)])])
4509
4510 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4511 ;; when the original load is a 4 byte instruction but the add and the
4512 ;; load are 2 2 byte instructions.
4513
4514 (define_split
4515 [(set (match_operand:DI 0 "register_operand" "")
4516 (mem:DI (plus:DI (match_dup 0)
4517 (match_operand:DI 1 "const_int_operand" ""))))]
4518 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4519 && GET_CODE (operands[0]) == REG
4520 && M16_REG_P (REGNO (operands[0]))
4521 && GET_CODE (operands[1]) == CONST_INT
4522 && ((INTVAL (operands[1]) < 0
4523 && INTVAL (operands[1]) >= -0x10)
4524 || (INTVAL (operands[1]) >= 32 * 8
4525 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4526 || (INTVAL (operands[1]) >= 0
4527 && INTVAL (operands[1]) < 32 * 8
4528 && (INTVAL (operands[1]) & 7) != 0))"
4529 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4530 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4531 "
4532 {
4533 HOST_WIDE_INT val = INTVAL (operands[1]);
4534
4535 if (val < 0)
4536 operands[2] = GEN_INT (0);
4537 else if (val >= 32 * 8)
4538 {
4539 int off = val & 7;
4540
4541 operands[1] = GEN_INT (0x8 + off);
4542 operands[2] = GEN_INT (val - off - 0x8);
4543 }
4544 else
4545 {
4546 int off = val & 7;
4547
4548 operands[1] = GEN_INT (off);
4549 operands[2] = GEN_INT (val - off);
4550 }
4551 }")
4552
4553 ;; Handle input reloads in DImode.
4554 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
4555 ;; see it as the source or the destination, depending upon which way
4556 ;; reload handles the instruction.
4557 ;; Making the second operand TImode is a trick. The compiler may
4558 ;; reuse the same register for operand 0 and operand 2. Using TImode
4559 ;; gives us two registers, so we can always use the one which is not
4560 ;; used.
4561
4562 (define_expand "reload_indi"
4563 [(set (match_operand:DI 0 "register_operand" "=b")
4564 (match_operand:DI 1 "movdi_operand" "b"))
4565 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
4566 "TARGET_64BIT"
4567 "
4568 {
4569 rtx scratch = gen_rtx (REG, DImode,
4570 (REGNO (operands[0]) == REGNO (operands[2])
4571 ? REGNO (operands[2]) + 1
4572 : REGNO (operands[2])));
4573
4574 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4575 {
4576 if (GET_CODE (operands[1]) == MEM)
4577 {
4578 rtx memword, offword, hiword, loword;
4579
4580 scratch = gen_rtx (REG, SImode, REGNO (scratch));
4581 memword = change_address (operands[1], SImode, NULL_RTX);
4582 offword = change_address (adj_offsettable_operand (operands[1], 4),
4583 SImode, NULL_RTX);
4584 if (BYTES_BIG_ENDIAN)
4585 {
4586 hiword = memword;
4587 loword = offword;
4588 }
4589 else
4590 {
4591 hiword = offword;
4592 loword = memword;
4593 }
4594 emit_move_insn (scratch, hiword);
4595 emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
4596 emit_move_insn (scratch, loword);
4597 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
4598 }
4599 else
4600 {
4601 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
4602 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
4603 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
4604 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
4605 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
4606 }
4607 DONE;
4608 }
4609 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
4610 {
4611 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
4612 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
4613 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
4614 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
4615 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
4616 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
4617 DONE;
4618 }
4619 /* This handles moves between a float register and HI/LO. */
4620 emit_move_insn (scratch, operands[1]);
4621 emit_move_insn (operands[0], scratch);
4622 DONE;
4623 }")
4624
4625 ;; Handle output reloads in DImode.
4626
4627 (define_expand "reload_outdi"
4628 [(set (match_operand:DI 0 "general_operand" "=b")
4629 (match_operand:DI 1 "se_register_operand" "b"))
4630 (clobber (match_operand:DI 2 "register_operand" "=&d"))]
4631 "TARGET_64BIT"
4632 "
4633 {
4634 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4635 {
4636 emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
4637 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), operands[2]));
4638 emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
4639 emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
4640 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), operands[2]));
4641 DONE;
4642 }
4643 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
4644 {
4645 if (GET_CODE (operands[0]) == MEM)
4646 {
4647 rtx scratch, memword, offword, hiword, loword;
4648
4649 scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
4650 memword = change_address (operands[0], SImode, NULL_RTX);
4651 offword = change_address (adj_offsettable_operand (operands[0], 4),
4652 SImode, NULL_RTX);
4653 if (BYTES_BIG_ENDIAN)
4654 {
4655 hiword = memword;
4656 loword = offword;
4657 }
4658 else
4659 {
4660 hiword = offword;
4661 loword = memword;
4662 }
4663 emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
4664 emit_move_insn (hiword, scratch);
4665 emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
4666 emit_move_insn (loword, scratch);
4667 }
4668 else
4669 {
4670 emit_insn (gen_movdi (operands[2], gen_rtx (REG, DImode, 65)));
4671 emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
4672 emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
4673 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
4674 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
4675 emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
4676 }
4677 DONE;
4678 }
4679 /* This handles moves between a float register and HI/LO. */
4680 emit_move_insn (operands[2], operands[1]);
4681 emit_move_insn (operands[0], operands[2]);
4682 DONE;
4683 }")
4684
4685 ;; 32-bit Integer moves
4686
4687 (define_split
4688 [(set (match_operand:SI 0 "register_operand" "")
4689 (match_operand:SI 1 "large_int" ""))]
4690 "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
4691 [(set (match_dup 0)
4692 (match_dup 2))
4693 (set (match_dup 0)
4694 (ior:SI (match_dup 0)
4695 (match_dup 3)))]
4696 "
4697 {
4698 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
4699 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
4700 }")
4701
4702 ;; Unlike most other insns, the move insns can't be split with
4703 ;; different predicates, because register spilling and other parts of
4704 ;; the compiler, have memoized the insn number already.
4705
4706 (define_expand "movsi"
4707 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4708 (match_operand:SI 1 "general_operand" ""))]
4709 ""
4710 "
4711 {
4712 if (mips_split_addresses && mips_check_split (operands[1], SImode))
4713 {
4714 enum machine_mode mode = GET_MODE (operands[0]);
4715 rtx tem = ((reload_in_progress | reload_completed)
4716 ? operands[0] : gen_reg_rtx (mode));
4717
4718 emit_insn (gen_rtx (SET, VOIDmode, tem,
4719 gen_rtx (HIGH, mode, operands[1])));
4720
4721 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4722 }
4723
4724 /* If we are generating embedded PIC code, and we are referring to a
4725 symbol in the .text section, we must use an offset from the start
4726 of the function. */
4727 if (TARGET_EMBEDDED_PIC
4728 && (GET_CODE (operands[1]) == LABEL_REF
4729 || (GET_CODE (operands[1]) == SYMBOL_REF
4730 && ! SYMBOL_REF_FLAG (operands[1]))))
4731 {
4732 rtx temp;
4733
4734 temp = embedded_pic_offset (operands[1]);
4735 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4736 force_reg (SImode, temp));
4737 emit_move_insn (operands[0], force_reg (SImode, temp));
4738 DONE;
4739 }
4740
4741 /* If operands[1] is a constant address invalid for pic, then we need to
4742 handle it just like LEGITIMIZE_ADDRESS does. */
4743 if (flag_pic && pic_address_needs_scratch (operands[1]))
4744 {
4745 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
4746 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4747
4748 if (! SMALL_INT (temp2))
4749 temp2 = force_reg (SImode, temp2);
4750
4751 emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
4752 DONE;
4753 }
4754
4755 /* On the mips16, we can handle a GP relative reference by adding in
4756 $gp. We need to check the name to see whether this is a string
4757 constant. */
4758 if (TARGET_MIPS16
4759 && register_operand (operands[0], SImode)
4760 && GET_CODE (operands[1]) == SYMBOL_REF
4761 && SYMBOL_REF_FLAG (operands[1]))
4762 {
4763 char *name = XSTR (operands[1], 0);
4764
4765 if (name[0] != '*'
4766 || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4767 sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4768 {
4769 rtx base_reg;
4770
4771 if (reload_in_progress || reload_completed)
4772 {
4773 /* We need to reload this address. In this case we
4774 aren't going to have a chance to combine loading the
4775 address with the load or store. That means that we
4776 can either generate a 2 byte move followed by a 4
4777 byte addition, or a 2 byte load with a 4 byte entry
4778 in the constant table. Since the entry in the
4779 constant table might be shared, we're better off, on
4780 average, loading the address from the constant table. */
4781 emit_move_insn (operands[0],
4782 force_const_mem (SImode, operands[1]));
4783 DONE;
4784 }
4785
4786 base_reg = gen_reg_rtx (Pmode);
4787 emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4788
4789 emit_move_insn (operands[0],
4790 gen_rtx (PLUS, SImode, base_reg,
4791 mips16_gp_offset (operands[1])));
4792 DONE;
4793 }
4794 }
4795
4796 if ((reload_in_progress | reload_completed) == 0
4797 && !register_operand (operands[0], SImode)
4798 && !register_operand (operands[1], SImode)
4799 && (TARGET_MIPS16
4800 || GET_CODE (operands[1]) != CONST_INT
4801 || INTVAL (operands[1]) != 0))
4802 {
4803 rtx temp = force_reg (SImode, operands[1]);
4804 emit_move_insn (operands[0], temp);
4805 DONE;
4806 }
4807 }")
4808
4809 ;; For mips16, we need a special case to handle storing $31 into
4810 ;; memory, since we don't have a constraint to match $31. This
4811 ;; instruction can be generated by save_restore_insns.
4812
4813 (define_insn ""
4814 [(set (match_operand:SI 0 "memory_operand" "R,m")
4815 (reg:SI 31))]
4816 "TARGET_MIPS16"
4817 "*
4818 {
4819 operands[1] = gen_rtx (REG, SImode, 31);
4820 return mips_move_1word (operands, insn, FALSE);
4821 }"
4822 [(set_attr "type" "store")
4823 (set_attr "mode" "SI")
4824 (set_attr "length" "1,2")])
4825
4826 ;; The difference between these two is whether or not ints are allowed
4827 ;; in FP registers (off by default, use -mdebugh to enable).
4828
4829 (define_insn "movsi_internal1"
4830 [(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")
4831 (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"))]
4832 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
4833 && (register_operand (operands[0], SImode)
4834 || register_operand (operands[1], SImode)
4835 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4836 "* return mips_move_1word (operands, insn, FALSE);"
4837 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
4838 (set_attr "mode" "SI")
4839 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
4840
4841 (define_insn "movsi_internal2"
4842 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
4843 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
4844 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
4845 && (register_operand (operands[0], SImode)
4846 || register_operand (operands[1], SImode)
4847 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4848 "* return mips_move_1word (operands, insn, FALSE);"
4849 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
4850 (set_attr "mode" "SI")
4851 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
4852
4853 ;; This is the mips16 movsi instruction. We accept a small integer as
4854 ;; the source if the destination is a GP memory reference. This is
4855 ;; because we want the combine pass to turn adding a GP reference to a
4856 ;; register into a direct GP reference, but the combine pass will pass
4857 ;; in the source as a constant if it finds an equivalent one. If the
4858 ;; instruction is recognized, reload will force the constant back out
4859 ;; into a register.
4860
4861 (define_insn ""
4862 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
4863 (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
4864 "TARGET_MIPS16
4865 && (register_operand (operands[0], SImode)
4866 || register_operand (operands[1], SImode)
4867 || (GET_CODE (operands[0]) == MEM
4868 && GET_CODE (XEXP (operands[0], 0)) == PLUS
4869 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
4870 && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
4871 && GET_CODE (operands[1]) == CONST_INT
4872 && (SMALL_INT (operands[1])
4873 || SMALL_INT_UNSIGNED (operands[1]))))"
4874 "* return mips_move_1word (operands, insn, FALSE);"
4875 [(set_attr "type" "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
4876 (set_attr "mode" "SI")
4877 (set_attr_alternative "length"
4878 [(const_int 1)
4879 (const_int 1)
4880 (const_int 1)
4881 (const_int 2)
4882 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4883 (const_int 1)
4884 (const_int 2))
4885 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4886 (const_int 2)
4887 (const_int 3))
4888 (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
4889 (const_int 1)
4890 (const_int 2))
4891 (const_int 1)
4892 (const_int 2)
4893 (const_int 1)
4894 (const_int 2)
4895 (const_int 1)
4896 (const_int 1)])])
4897
4898 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4899 ;; when the original load is a 4 byte instruction but the add and the
4900 ;; load are 2 2 byte instructions.
4901
4902 (define_split
4903 [(set (match_operand:SI 0 "register_operand" "")
4904 (mem:SI (plus:SI (match_dup 0)
4905 (match_operand:SI 1 "const_int_operand" ""))))]
4906 "TARGET_MIPS16 && reload_completed
4907 && GET_CODE (operands[0]) == REG
4908 && M16_REG_P (REGNO (operands[0]))
4909 && GET_CODE (operands[1]) == CONST_INT
4910 && ((INTVAL (operands[1]) < 0
4911 && INTVAL (operands[1]) >= -0x80)
4912 || (INTVAL (operands[1]) >= 32 * 4
4913 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4914 || (INTVAL (operands[1]) >= 0
4915 && INTVAL (operands[1]) < 32 * 4
4916 && (INTVAL (operands[1]) & 3) != 0))"
4917 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4918 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4919 "
4920 {
4921 HOST_WIDE_INT val = INTVAL (operands[1]);
4922
4923 if (val < 0)
4924 operands[2] = GEN_INT (0);
4925 else if (val >= 32 * 4)
4926 {
4927 int off = val & 3;
4928
4929 operands[1] = GEN_INT (0x7c + off);
4930 operands[2] = GEN_INT (val - off - 0x7c);
4931 }
4932 else
4933 {
4934 int off = val & 3;
4935
4936 operands[1] = GEN_INT (off);
4937 operands[2] = GEN_INT (val - off);
4938 }
4939 }")
4940
4941 ;; On the mips16, we can split a load of certain constants into a load
4942 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4943 ;; instructions.
4944
4945 (define_split
4946 [(set (match_operand:SI 0 "register_operand" "")
4947 (match_operand:SI 1 "const_int_operand" ""))]
4948 "TARGET_MIPS16 && reload_completed
4949 && GET_CODE (operands[0]) == REG
4950 && M16_REG_P (REGNO (operands[0]))
4951 && GET_CODE (operands[1]) == CONST_INT
4952 && INTVAL (operands[1]) >= 0x100
4953 && INTVAL (operands[1]) <= 0xff + 0x7f"
4954 [(set (match_dup 0) (match_dup 1))
4955 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4956 "
4957 {
4958 int val = INTVAL (operands[1]);
4959
4960 operands[1] = GEN_INT (0xff);
4961 operands[2] = GEN_INT (val - 0xff);
4962 }")
4963
4964 ;; On the mips16, we can split a load of a negative constant into a
4965 ;; load and a neg. That's what mips_move_1word will generate anyhow.
4966
4967 (define_split
4968 [(set (match_operand:SI 0 "register_operand" "")
4969 (match_operand:SI 1 "const_int_operand" ""))]
4970 "TARGET_MIPS16 && reload_completed
4971 && GET_CODE (operands[0]) == REG
4972 && M16_REG_P (REGNO (operands[0]))
4973 && GET_CODE (operands[1]) == CONST_INT
4974 && INTVAL (operands[1]) < 0
4975 && INTVAL (operands[1]) > - 0x8000"
4976 [(set (match_dup 0) (match_dup 1))
4977 (set (match_dup 0) (neg:SI (match_dup 0)))]
4978 "
4979 {
4980 operands[1] = GEN_INT (- INTVAL (operands[1]));
4981 }")
4982
4983 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
4984 ;; order to set the sign bit correctly in the HI register.
4985
4986 (define_expand "reload_outsi"
4987 [(set (match_operand:SI 0 "general_operand" "=b")
4988 (match_operand:SI 1 "register_operand" "b"))
4989 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
4990 "TARGET_64BIT || TARGET_MIPS16"
4991 "
4992 {
4993 if (TARGET_64BIT
4994 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4995 {
4996 emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
4997 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
4998 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
4999 DONE;
5000 }
5001 /* Use a mult to reload LO on mips16. ??? This is hideous. */
5002 if (TARGET_MIPS16
5003 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5004 {
5005 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5006 /* This is gen_mulsi3_internal, but we need to fill in the
5007 scratch registers. */
5008 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5009 gen_rtvec (3,
5010 gen_rtx (SET, VOIDmode,
5011 operands[0],
5012 gen_rtx (MULT, SImode,
5013 operands[1],
5014 operands[2])),
5015 gen_rtx (CLOBBER, VOIDmode,
5016 gen_rtx (REG, SImode, 64)),
5017 gen_rtx (CLOBBER, VOIDmode,
5018 gen_rtx (REG, SImode, 66)))));
5019 DONE;
5020 }
5021 /* FIXME: I don't know how to get a value into the HI register. */
5022 if (GET_CODE (operands[0]) == REG && GP_REG_P (operands[0]))
5023 {
5024 emit_move_insn (operands[0], operands[1]);
5025 DONE;
5026 }
5027 /* This handles moves between a float register and HI/LO. */
5028 emit_move_insn (operands[2], operands[1]);
5029 emit_move_insn (operands[0], operands[2]);
5030 DONE;
5031 }")
5032
5033 ;; Reload a value into HI or LO. There is no mthi or mtlo on mips16,
5034 ;; so we use a mult. ??? This is hideous, and we ought to figure out
5035 ;; something better.
5036
5037 (define_expand "reload_insi"
5038 [(set (match_operand:SI 0 "register_operand" "=b")
5039 (match_operand:SI 1 "register_operand" "b"))
5040 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5041 "TARGET_MIPS16"
5042 "
5043 {
5044 if (TARGET_MIPS16
5045 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5046 {
5047 emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5048 /* This is gen_mulsi3_internal, but we need to fill in the
5049 scratch registers. */
5050 emit_insn (gen_rtx (PARALLEL, VOIDmode,
5051 gen_rtvec (3,
5052 gen_rtx (SET, VOIDmode,
5053 operands[0],
5054 gen_rtx (MULT, SImode,
5055 operands[1],
5056 operands[2])),
5057 gen_rtx (CLOBBER, VOIDmode,
5058 gen_rtx (REG, SImode, 64)),
5059 gen_rtx (CLOBBER, VOIDmode,
5060 gen_rtx (REG, SImode, 66)))));
5061 DONE;
5062 }
5063 /* FIXME: I don't know how to get a value into the HI register. */
5064 emit_move_insn (operands[0], operands[1]);
5065 DONE;
5066 }")
5067
5068 ;; This insn handles moving CCmode values. It's really just a
5069 ;; slightly simplified copy of movsi_internal2, with additional cases
5070 ;; to move a condition register to a general register and to move
5071 ;; between the general registers and the floating point registers.
5072
5073 (define_insn "movcc"
5074 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5075 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5076 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5077 "* return mips_move_1word (operands, insn, FALSE);"
5078 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5079 (set_attr "mode" "SI")
5080 (set_attr "length" "2,1,1,2,1,2,1,1,1,1,2,1,2")])
5081
5082 ;; Reload condition code registers. These need scratch registers.
5083
5084 (define_expand "reload_incc"
5085 [(set (match_operand:CC 0 "register_operand" "=z")
5086 (match_operand:CC 1 "general_operand" "z"))
5087 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5088 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5089 "
5090 {
5091 rtx source;
5092 rtx fp1, fp2;
5093
5094 /* This is called when are copying some value into a condition code
5095 register. Operand 0 is the condition code register. Operand 1
5096 is the source. Operand 2 is a scratch register; we use TFmode
5097 because we actually need two floating point registers. */
5098 if (! ST_REG_P (true_regnum (operands[0]))
5099 || ! FP_REG_P (true_regnum (operands[2])))
5100 abort ();
5101
5102 /* We need to get the source in SFmode so that the insn is
5103 recognized. */
5104 if (GET_CODE (operands[1]) == MEM)
5105 source = change_address (operands[1], SFmode, NULL_RTX);
5106 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5107 source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
5108 else
5109 source = operands[1];
5110
5111 fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
5112 fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
5113
5114 emit_insn (gen_move_insn (fp1, source));
5115 emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
5116 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
5117 gen_rtx (LT, CCmode, fp2, fp1)));
5118
5119 DONE;
5120 }")
5121
5122 (define_expand "reload_outcc"
5123 [(set (match_operand:CC 0 "general_operand" "=z")
5124 (match_operand:CC 1 "register_operand" "z"))
5125 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5126 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5127 "
5128 {
5129 /* This is called when we are copying a condition code register out
5130 to save it somewhere. Operand 0 should be the location we are
5131 going to save it to. Operand 1 should be the condition code
5132 register. Operand 2 should be a scratch general purpose register
5133 created for us by reload. The mips_secondary_reload_class
5134 function should have told reload that we don't need a scratch
5135 register if the destination is a general purpose register anyhow. */
5136 if (ST_REG_P (true_regnum (operands[0]))
5137 || GP_REG_P (true_regnum (operands[0]))
5138 || ! ST_REG_P (true_regnum (operands[1]))
5139 || ! GP_REG_P (true_regnum (operands[2])))
5140 abort ();
5141
5142 /* All we have to do is copy the value from the condition code to
5143 the data register, which movcc can handle, and then store the
5144 value into the real final destination. */
5145 emit_insn (gen_move_insn (operands[2], operands[1]));
5146 emit_insn (gen_move_insn (operands[0], operands[2]));
5147
5148 DONE;
5149 }")
5150
5151 ;; MIPS4 supports loading and storing a floating point register from
5152 ;; the sum of two general registers. We use two versions for each of
5153 ;; these four instructions: one where the two general registers are
5154 ;; SImode, and one where they are DImode. This is because general
5155 ;; registers will be in SImode when they hold 32 bit values, but,
5156 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5157 ;; instructions will still work correctly.
5158
5159 ;; ??? Perhaps it would be better to support these instructions by
5160 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
5161 ;; these instructions can only be used to load and store floating
5162 ;; point registers, that would probably cause trouble in reload.
5163
5164 (define_insn ""
5165 [(set (match_operand:SF 0 "register_operand" "=f")
5166 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5167 (match_operand:SI 2 "register_operand" "d"))))]
5168 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5169 "lwxc1\\t%0,%1(%2)"
5170 [(set_attr "type" "load")
5171 (set_attr "mode" "SF")
5172 (set_attr "length" "1")])
5173
5174 (define_insn ""
5175 [(set (match_operand:SF 0 "register_operand" "=f")
5176 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5177 (match_operand:DI 2 "se_register_operand" "d"))))]
5178 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5179 "lwxc1\\t%0,%1(%2)"
5180 [(set_attr "type" "load")
5181 (set_attr "mode" "SF")
5182 (set_attr "length" "1")])
5183
5184 (define_insn ""
5185 [(set (match_operand:DF 0 "register_operand" "=f")
5186 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5187 (match_operand:SI 2 "register_operand" "d"))))]
5188 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5189 "ldxc1\\t%0,%1(%2)"
5190 [(set_attr "type" "load")
5191 (set_attr "mode" "DF")
5192 (set_attr "length" "1")])
5193
5194 (define_insn ""
5195 [(set (match_operand:DF 0 "register_operand" "=f")
5196 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5197 (match_operand:DI 2 "se_register_operand" "d"))))]
5198 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5199 "ldxc1\\t%0,%1(%2)"
5200 [(set_attr "type" "load")
5201 (set_attr "mode" "DF")
5202 (set_attr "length" "1")])
5203
5204 (define_insn ""
5205 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5206 (match_operand:SI 2 "register_operand" "d")))
5207 (match_operand:SF 0 "register_operand" "=f"))]
5208 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5209 "swxc1\\t%0,%1(%2)"
5210 [(set_attr "type" "store")
5211 (set_attr "mode" "SF")
5212 (set_attr "length" "1")])
5213
5214 (define_insn ""
5215 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5216 (match_operand:DI 2 "se_register_operand" "d")))
5217 (match_operand:SF 0 "register_operand" "=f"))]
5218 "mips_isa >= 4 && TARGET_HARD_FLOAT"
5219 "swxc1\\t%0,%1(%2)"
5220 [(set_attr "type" "store")
5221 (set_attr "mode" "SF")
5222 (set_attr "length" "1")])
5223
5224 (define_insn ""
5225 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5226 (match_operand:SI 2 "register_operand" "d")))
5227 (match_operand:DF 0 "register_operand" "=f"))]
5228 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5229 "sdxc1\\t%0,%1(%2)"
5230 [(set_attr "type" "store")
5231 (set_attr "mode" "DF")
5232 (set_attr "length" "1")])
5233
5234 (define_insn ""
5235 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5236 (match_operand:DI 2 "se_register_operand" "d")))
5237 (match_operand:DF 0 "register_operand" "=f"))]
5238 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5239 "sdxc1\\t%0,%1(%2)"
5240 [(set_attr "type" "store")
5241 (set_attr "mode" "DF")
5242 (set_attr "length" "1")])
5243
5244 ;; 16-bit Integer moves
5245
5246 ;; Unlike most other insns, the move insns can't be split with
5247 ;; different predicates, because register spilling and other parts of
5248 ;; the compiler, have memoized the insn number already.
5249 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5250
5251 (define_expand "movhi"
5252 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5253 (match_operand:HI 1 "general_operand" ""))]
5254 ""
5255 "
5256 {
5257 if ((reload_in_progress | reload_completed) == 0
5258 && !register_operand (operands[0], HImode)
5259 && !register_operand (operands[1], HImode)
5260 && (TARGET_MIPS16
5261 || (GET_CODE (operands[1]) != CONST_INT
5262 || INTVAL (operands[1]) != 0)))
5263 {
5264 rtx temp = force_reg (HImode, operands[1]);
5265 emit_move_insn (operands[0], temp);
5266 DONE;
5267 }
5268 }")
5269
5270 ;; The difference between these two is whether or not ints are allowed
5271 ;; in FP registers (off by default, use -mdebugh to enable).
5272
5273 (define_insn "movhi_internal1"
5274 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5275 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5276 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5277 && (register_operand (operands[0], HImode)
5278 || register_operand (operands[1], HImode)
5279 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5280 "* return mips_move_1word (operands, insn, TRUE);"
5281 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5282 (set_attr "mode" "HI")
5283 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
5284
5285 (define_insn "movhi_internal2"
5286 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5287 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5288 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5289 && (register_operand (operands[0], HImode)
5290 || register_operand (operands[1], HImode)
5291 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5292 "* return mips_move_1word (operands, insn, TRUE);"
5293 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5294 (set_attr "mode" "HI")
5295 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
5296
5297 (define_insn ""
5298 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5299 (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5300 "TARGET_MIPS16
5301 && (register_operand (operands[0], HImode)
5302 || register_operand (operands[1], HImode))"
5303 "* return mips_move_1word (operands, insn, TRUE);"
5304 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5305 (set_attr "mode" "HI")
5306 (set_attr_alternative "length"
5307 [(const_int 1)
5308 (const_int 1)
5309 (const_int 1)
5310 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5311 (const_int 1)
5312 (const_int 2))
5313 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5314 (const_int 2)
5315 (const_int 3))
5316 (const_int 1)
5317 (const_int 2)
5318 (const_int 1)
5319 (const_int 2)
5320 (const_int 1)])])
5321
5322
5323 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
5324 ;; when the original load is a 4 byte instruction but the add and the
5325 ;; load are 2 2 byte instructions.
5326
5327 (define_split
5328 [(set (match_operand:HI 0 "register_operand" "")
5329 (mem:SI (plus:SI (match_dup 0)
5330 (match_operand:SI 1 "const_int_operand" ""))))]
5331 "TARGET_MIPS16 && reload_completed
5332 && GET_CODE (operands[0]) == REG
5333 && M16_REG_P (REGNO (operands[0]))
5334 && GET_CODE (operands[1]) == CONST_INT
5335 && ((INTVAL (operands[1]) < 0
5336 && INTVAL (operands[1]) >= -0x80)
5337 || (INTVAL (operands[1]) >= 32 * 2
5338 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5339 || (INTVAL (operands[1]) >= 0
5340 && INTVAL (operands[1]) < 32 * 2
5341 && (INTVAL (operands[1]) & 1) != 0))"
5342 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5343 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5344 "
5345 {
5346 HOST_WIDE_INT val = INTVAL (operands[1]);
5347
5348 if (val < 0)
5349 operands[2] = GEN_INT (0);
5350 else if (val >= 32 * 2)
5351 {
5352 int off = val & 1;
5353
5354 operands[1] = GEN_INT (0x7e + off);
5355 operands[2] = GEN_INT (val - off - 0x7e);
5356 }
5357 else
5358 {
5359 int off = val & 1;
5360
5361 operands[1] = GEN_INT (off);
5362 operands[2] = GEN_INT (val - off);
5363 }
5364 }")
5365
5366 ;; 8-bit Integer moves
5367
5368 ;; Unlike most other insns, the move insns can't be split with
5369 ;; different predicates, because register spilling and other parts of
5370 ;; the compiler, have memoized the insn number already.
5371 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5372
5373 (define_expand "movqi"
5374 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5375 (match_operand:QI 1 "general_operand" ""))]
5376 ""
5377 "
5378 {
5379 if ((reload_in_progress | reload_completed) == 0
5380 && !register_operand (operands[0], QImode)
5381 && !register_operand (operands[1], QImode)
5382 && (TARGET_MIPS16
5383 || (GET_CODE (operands[1]) != CONST_INT
5384 || INTVAL (operands[1]) != 0)))
5385 {
5386 rtx temp = force_reg (QImode, operands[1]);
5387 emit_move_insn (operands[0], temp);
5388 DONE;
5389 }
5390 }")
5391
5392 ;; The difference between these two is whether or not ints are allowed
5393 ;; in FP registers (off by default, use -mdebugh to enable).
5394
5395 (define_insn "movqi_internal1"
5396 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
5397 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5398 "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5399 && (register_operand (operands[0], QImode)
5400 || register_operand (operands[1], QImode)
5401 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5402 "* return mips_move_1word (operands, insn, TRUE);"
5403 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5404 (set_attr "mode" "QI")
5405 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
5406
5407 (define_insn "movqi_internal2"
5408 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5409 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5410 "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5411 && (register_operand (operands[0], QImode)
5412 || register_operand (operands[1], QImode)
5413 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5414 "* return mips_move_1word (operands, insn, TRUE);"
5415 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5416 (set_attr "mode" "QI")
5417 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
5418
5419 (define_insn ""
5420 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5421 (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
5422 "TARGET_MIPS16
5423 && (register_operand (operands[0], QImode)
5424 || register_operand (operands[1], QImode))"
5425 "* return mips_move_1word (operands, insn, TRUE);"
5426 [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
5427 (set_attr "mode" "QI")
5428 (set_attr_alternative "length"
5429 [(const_int 1)
5430 (const_int 1)
5431 (const_int 1)
5432 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5433 (const_int 1)
5434 (const_int 2))
5435 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5436 (const_int 2)
5437 (const_int 3))
5438 (const_int 1)
5439 (const_int 2)
5440 (const_int 1)
5441 (const_int 2)
5442 (const_int 1)])])
5443
5444
5445 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5446 ;; when the original load is a 4 byte instruction but the add and the
5447 ;; load are 2 2 byte instructions.
5448
5449 (define_split
5450 [(set (match_operand:QI 0 "register_operand" "")
5451 (mem:QI (plus:SI (match_dup 0)
5452 (match_operand:SI 1 "const_int_operand" ""))))]
5453 "TARGET_MIPS16 && reload_completed
5454 && GET_CODE (operands[0]) == REG
5455 && M16_REG_P (REGNO (operands[0]))
5456 && GET_CODE (operands[1]) == CONST_INT
5457 && ((INTVAL (operands[1]) < 0
5458 && INTVAL (operands[1]) >= -0x80)
5459 || (INTVAL (operands[1]) >= 32
5460 && INTVAL (operands[1]) <= 31 + 0x7f))"
5461 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5462 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5463 "
5464 {
5465 HOST_WIDE_INT val = INTVAL (operands[1]);
5466
5467 if (val < 0)
5468 operands[2] = GEN_INT (0);
5469 else
5470 {
5471 operands[1] = GEN_INT (0x7f);
5472 operands[2] = GEN_INT (val - 0x7f);
5473 }
5474 }")
5475
5476 ;; 32-bit floating point moves
5477
5478 (define_expand "movsf"
5479 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5480 (match_operand:SF 1 "general_operand" ""))]
5481 ""
5482 "
5483 {
5484 if ((reload_in_progress | reload_completed) == 0
5485 && !register_operand (operands[0], SFmode)
5486 && !register_operand (operands[1], SFmode)
5487 && (TARGET_MIPS16
5488 || (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5489 && operands[1] != CONST0_RTX (SFmode)))
5490 {
5491 rtx temp = force_reg (SFmode, operands[1]);
5492 emit_move_insn (operands[0], temp);
5493 DONE;
5494 }
5495 }")
5496
5497 (define_insn "movsf_internal1"
5498 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
5499 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
5500 "TARGET_HARD_FLOAT
5501 && (register_operand (operands[0], SFmode)
5502 || register_operand (operands[1], SFmode)
5503 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5504 || operands[1] == CONST0_RTX (SFmode))"
5505 "* return mips_move_1word (operands, insn, FALSE);"
5506 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
5507 (set_attr "mode" "SF")
5508 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")])
5509
5510
5511 (define_insn "movsf_internal2"
5512 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
5513 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
5514 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5515 && (register_operand (operands[0], SFmode)
5516 || register_operand (operands[1], SFmode)
5517 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5518 || operands[1] == CONST0_RTX (SFmode))"
5519 "* return mips_move_1word (operands, insn, FALSE);"
5520 [(set_attr "type" "move,load,load,store,store")
5521 (set_attr "mode" "SF")
5522 (set_attr "length" "1,1,2,1,2")])
5523
5524 (define_insn ""
5525 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
5526 (match_operand:SF 1 "general_operand" "d,d,y,R,Fm,d,d"))]
5527 "TARGET_MIPS16
5528 && (register_operand (operands[0], SFmode)
5529 || register_operand (operands[1], SFmode))"
5530 "* return mips_move_1word (operands, insn, FALSE);"
5531 [(set_attr "type" "move,move,move,load,load,store,store")
5532 (set_attr "mode" "SF")
5533 (set_attr "length" "1,1,1,1,2,1,2")])
5534
5535
5536 ;; 64-bit floating point moves
5537
5538 (define_expand "movdf"
5539 [(set (match_operand:DF 0 "nonimmediate_operand" "")
5540 (match_operand:DF 1 "general_operand" ""))]
5541 ""
5542 "
5543 {
5544 if ((reload_in_progress | reload_completed) == 0
5545 && !register_operand (operands[0], DFmode)
5546 && !register_operand (operands[1], DFmode)
5547 && (TARGET_MIPS16
5548 || (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5549 && operands[1] != CONST0_RTX (DFmode)))
5550 {
5551 rtx temp = force_reg (DFmode, operands[1]);
5552 emit_move_insn (operands[0], temp);
5553 DONE;
5554 }
5555 }")
5556
5557 (define_insn "movdf_internal1"
5558 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
5559 (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
5560 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
5561 && TARGET_DOUBLE_FLOAT
5562 && (register_operand (operands[0], DFmode)
5563 || register_operand (operands[1], DFmode)
5564 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5565 || operands[1] == CONST0_RTX (DFmode))"
5566 "* return mips_move_2words (operands, insn); "
5567 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
5568 (set_attr "mode" "DF")
5569 (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")])
5570
5571 (define_insn "movdf_internal1a"
5572 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,f,*d,*d,*d,*To,*R")
5573 (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,F,*F,*To,*R,*d,*d"))]
5574 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
5575 && TARGET_DOUBLE_FLOAT
5576 && (register_operand (operands[0], DFmode)
5577 || register_operand (operands[1], DFmode))
5578 || (GET_CODE (operands [0]) == MEM
5579 && ((GET_CODE (operands[1]) == CONST_INT
5580 && INTVAL (operands[1]) == 0)
5581 || operands[1] == CONST0_RTX (DFmode)))"
5582 "* return mips_move_2words (operands, insn); "
5583 [(set_attr "type" "move,load,store,store,store,store,load,load,load,load,store,store")
5584 (set_attr "mode" "DF")
5585 (set_attr "length" "1,2,1,1,2,2,2,2,2,1,2,1")])
5586
5587 (define_insn "movdf_internal2"
5588 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To")
5589 (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d"))]
5590 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
5591 && (register_operand (operands[0], DFmode)
5592 || register_operand (operands[1], DFmode)
5593 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5594 || operands[1] == CONST0_RTX (DFmode))"
5595 "* return mips_move_2words (operands, insn); "
5596 [(set_attr "type" "move,load,load,store,store")
5597 (set_attr "mode" "DF")
5598 (set_attr "length" "2,2,4,2,4")])
5599
5600 (define_insn ""
5601 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
5602 (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
5603 "TARGET_MIPS16
5604 && (register_operand (operands[0], DFmode)
5605 || register_operand (operands[1], DFmode))"
5606 "* return mips_move_2words (operands, insn);"
5607 [(set_attr "type" "move,move,move,load,load,store,store")
5608 (set_attr "mode" "DF")
5609 (set_attr "length" "2,2,2,2,4,2,4")])
5610
5611 (define_split
5612 [(set (match_operand:DF 0 "register_operand" "")
5613 (match_operand:DF 1 "register_operand" ""))]
5614 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5615 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5616 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5617 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5618 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
5619 "")
5620
5621 ;; Instructions to load the global pointer register.
5622 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
5623 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
5624
5625 (define_insn "loadgp"
5626 [(set (reg:DI 28)
5627 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")] 2))
5628 (clobber (reg:DI 1))]
5629 ""
5630 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,$25%]"
5631 [(set_attr "type" "move")
5632 (set_attr "mode" "DI")
5633 (set_attr "length" "3")])
5634 \f
5635 ;; Block moves, see mips.c for more details.
5636 ;; Argument 0 is the destination
5637 ;; Argument 1 is the source
5638 ;; Argument 2 is the length
5639 ;; Argument 3 is the alignment
5640
5641 (define_expand "movstrsi"
5642 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5643 (match_operand:BLK 1 "general_operand" ""))
5644 (use (match_operand:SI 2 "arith32_operand" ""))
5645 (use (match_operand:SI 3 "immediate_operand" ""))])]
5646 "!TARGET_MIPS16"
5647 "
5648 {
5649 if (operands[0]) /* avoid unused code messages */
5650 {
5651 expand_block_move (operands);
5652 DONE;
5653 }
5654 }")
5655
5656 ;; Insn generated by block moves
5657
5658 (define_insn "movstrsi_internal"
5659 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
5660 (match_operand:BLK 1 "memory_operand" "o")) ;; source
5661 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5662 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5663 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5664 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5665 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5666 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5667 (use (const_int 0))] ;; normal block move
5668 ""
5669 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5670 [(set_attr "type" "store")
5671 (set_attr "mode" "none")
5672 (set_attr "length" "20")])
5673
5674 ;; We need mips16 versions, because an offset from the stack pointer
5675 ;; is not offsettable, since the stack pointer can only handle 4 and 8
5676 ;; byte loads.
5677
5678 (define_insn ""
5679 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
5680 (match_operand:BLK 1 "memory_operand" "d")) ;; source
5681 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5682 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5683 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5684 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5685 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5686 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5687 (use (const_int 0))] ;; normal block move
5688 "TARGET_MIPS16"
5689 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5690 [(set_attr "type" "multi")
5691 (set_attr "mode" "none")
5692 (set_attr "length" "20")])
5693
5694 (define_insn ""
5695 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
5696 (match_operand:BLK 1 "memory_operand" "o")) ;; source
5697 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5698 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5699 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5700 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5701 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5702 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5703 (use (const_int 0))] ;; normal block move
5704 "TARGET_MIPS16"
5705 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5706 [(set_attr "type" "multi")
5707 (set_attr "mode" "none")
5708 (set_attr "length" "20")])
5709
5710 (define_insn ""
5711 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
5712 (match_operand:BLK 1 "memory_operand" "d")) ;; source
5713 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5714 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5715 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5716 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5717 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5718 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5719 (use (const_int 0))] ;; normal block move
5720 "TARGET_MIPS16"
5721 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5722 [(set_attr "type" "multi")
5723 (set_attr "mode" "none")
5724 (set_attr "length" "20")])
5725
5726 ;; Split a block move into 2 parts, the first part is everything
5727 ;; except for the last move, and the second part is just the last
5728 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
5729 ;; fill a delay slot. This also prevents a bug in delayed branches
5730 ;; from showing up, which reuses one of the registers in our clobbers.
5731
5732 (define_split
5733 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
5734 (mem:BLK (match_operand:SI 1 "register_operand" "")))
5735 (clobber (match_operand:SI 4 "register_operand" ""))
5736 (clobber (match_operand:SI 5 "register_operand" ""))
5737 (clobber (match_operand:SI 6 "register_operand" ""))
5738 (clobber (match_operand:SI 7 "register_operand" ""))
5739 (use (match_operand:SI 2 "small_int" ""))
5740 (use (match_operand:SI 3 "small_int" ""))
5741 (use (const_int 0))]
5742
5743 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
5744
5745 ;; All but the last move
5746 [(parallel [(set (mem:BLK (match_dup 0))
5747 (mem:BLK (match_dup 1)))
5748 (clobber (match_dup 4))
5749 (clobber (match_dup 5))
5750 (clobber (match_dup 6))
5751 (clobber (match_dup 7))
5752 (use (match_dup 2))
5753 (use (match_dup 3))
5754 (use (const_int 1))])
5755
5756 ;; The last store, so it can fill a delay slot
5757 (parallel [(set (mem:BLK (match_dup 0))
5758 (mem:BLK (match_dup 1)))
5759 (clobber (match_dup 4))
5760 (clobber (match_dup 5))
5761 (clobber (match_dup 6))
5762 (clobber (match_dup 7))
5763 (use (match_dup 2))
5764 (use (match_dup 3))
5765 (use (const_int 2))])]
5766
5767 "")
5768
5769 (define_insn "movstrsi_internal2"
5770 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
5771 (match_operand:BLK 1 "memory_operand" "o")) ;; source
5772 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5773 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5774 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5775 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5776 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5777 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5778 (use (const_int 1))] ;; all but last store
5779 ""
5780 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
5781 [(set_attr "type" "store")
5782 (set_attr "mode" "none")
5783 (set_attr "length" "20")])
5784
5785 (define_insn ""
5786 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
5787 (match_operand:BLK 1 "memory_operand" "d")) ;; source
5788 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5789 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5790 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5791 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5792 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5793 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5794 (use (const_int 1))] ;; all but last store
5795 "TARGET_MIPS16"
5796 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
5797 [(set_attr "type" "multi")
5798 (set_attr "mode" "none")
5799 (set_attr "length" "20")])
5800
5801 (define_insn "movstrsi_internal3"
5802 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
5803 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
5804 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5805 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5806 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5807 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5808 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5809 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5810 (use (const_int 2))] ;; just last store of block move
5811 ""
5812 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
5813 [(set_attr "type" "store")
5814 (set_attr "mode" "none")
5815 (set_attr "length" "1")])
5816
5817 (define_insn ""
5818 [(set (match_operand:BLK 0 "memory_operand" "=d") ;; destination
5819 (match_operand:BLK 1 "memory_operand" "d")) ;; source
5820 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
5821 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
5822 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
5823 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
5824 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
5825 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
5826 (use (const_int 2))] ;; just last store of block move
5827 "TARGET_MIPS16"
5828 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
5829 [(set_attr "type" "store")
5830 (set_attr "mode" "none")
5831 (set_attr "length" "1")])
5832
5833 \f
5834 ;;
5835 ;; ....................
5836 ;;
5837 ;; SHIFTS
5838 ;;
5839 ;; ....................
5840
5841 ;; Many of these instructions uses trivial define_expands, because we
5842 ;; want to use a different set of constraints when TARGET_MIPS16.
5843
5844 (define_expand "ashlsi3"
5845 [(set (match_operand:SI 0 "register_operand" "=d")
5846 (ashift:SI (match_operand:SI 1 "register_operand" "d")
5847 (match_operand:SI 2 "arith_operand" "dI")))]
5848 ""
5849 "
5850 {
5851 /* On the mips16, a shift of more than 8 is a four byte instruction,
5852 so, for a shift between 8 and 16, it is just as fast to do two
5853 shifts of 8 or less. If there is a lot of shifting going on, we
5854 may win in CSE. Otherwise combine will put the shifts back
5855 together again. This can be called by function_arg, so we must
5856 be careful not to allocate a new register if we've reached the
5857 reload pass. */
5858 if (TARGET_MIPS16
5859 && optimize
5860 && GET_CODE (operands[2]) == CONST_INT
5861 && INTVAL (operands[2]) > 8
5862 && INTVAL (operands[2]) <= 16
5863 && ! reload_in_progress
5864 && ! reload_completed)
5865 {
5866 rtx temp = gen_reg_rtx (SImode);
5867
5868 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
5869 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
5870 GEN_INT (INTVAL (operands[2]) - 8)));
5871 DONE;
5872 }
5873 }")
5874
5875 (define_insn "ashlsi3_internal1"
5876 [(set (match_operand:SI 0 "register_operand" "=d")
5877 (ashift:SI (match_operand:SI 1 "register_operand" "d")
5878 (match_operand:SI 2 "arith_operand" "dI")))]
5879 "!TARGET_MIPS16"
5880 "*
5881 {
5882 if (GET_CODE (operands[2]) == CONST_INT)
5883 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
5884
5885 return \"sll\\t%0,%1,%2\";
5886 }"
5887 [(set_attr "type" "arith")
5888 (set_attr "mode" "SI")
5889 (set_attr "length" "1")])
5890
5891 (define_insn "ashlsi3_internal2"
5892 [(set (match_operand:SI 0 "register_operand" "=d,d")
5893 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
5894 (match_operand:SI 2 "arith_operand" "d,I")))]
5895 "TARGET_MIPS16"
5896 "*
5897 {
5898 if (which_alternative == 0)
5899 return \"sll\\t%0,%2\";
5900
5901 if (GET_CODE (operands[2]) == CONST_INT)
5902 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
5903
5904 return \"sll\\t%0,%1,%2\";
5905 }"
5906 [(set_attr "type" "arith")
5907 (set_attr "mode" "SI")
5908 (set_attr_alternative "length"
5909 [(const_int 1)
5910 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5911 (const_int 1)
5912 (const_int 2))])])
5913
5914 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5915
5916 (define_split
5917 [(set (match_operand:SI 0 "register_operand" "")
5918 (ashift:SI (match_operand:SI 1 "register_operand" "")
5919 (match_operand:SI 2 "const_int_operand" "")))]
5920 "TARGET_MIPS16
5921 && reload_completed
5922 && GET_CODE (operands[2]) == CONST_INT
5923 && INTVAL (operands[2]) > 8
5924 && INTVAL (operands[2]) <= 16"
5925 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5926 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5927 "
5928 {
5929 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
5930 }")
5931
5932 (define_expand "ashldi3"
5933 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5934 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
5935 (match_operand:SI 2 "arith_operand" "")))
5936 (clobber (match_dup 3))])]
5937 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5938 "
5939 {
5940 if (TARGET_64BIT)
5941 {
5942 /* On the mips16, a shift of more than 8 is a four byte
5943 instruction, so, for a shift between 8 and 16, it is just as
5944 fast to do two shifts of 8 or less. If there is a lot of
5945 shifting going on, we may win in CSE. Otherwise combine will
5946 put the shifts back together again. This can be called by
5947 function_arg, so we must be careful not to allocate a new
5948 register if we've reached the reload pass. */
5949 if (TARGET_MIPS16
5950 && optimize
5951 && GET_CODE (operands[2]) == CONST_INT
5952 && INTVAL (operands[2]) > 8
5953 && INTVAL (operands[2]) <= 16
5954 && ! reload_in_progress
5955 && ! reload_completed)
5956 {
5957 rtx temp = gen_reg_rtx (DImode);
5958
5959 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
5960 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
5961 GEN_INT (INTVAL (operands[2]) - 8)));
5962 DONE;
5963 }
5964
5965 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
5966 operands[2]));
5967 DONE;
5968 }
5969
5970 operands[3] = gen_reg_rtx (SImode);
5971 }")
5972
5973
5974 (define_insn "ashldi3_internal"
5975 [(set (match_operand:DI 0 "register_operand" "=&d")
5976 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5977 (match_operand:SI 2 "register_operand" "d")))
5978 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5979 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5980 "*
5981 {
5982 operands[4] = const0_rtx;
5983 dslots_jump_total += 3;
5984 dslots_jump_filled += 2;
5985
5986 return \"sll\\t%3,%2,26\\n\\
5987 \\tbgez\\t%3,1f\\n\\
5988 \\tsll\\t%M0,%L1,%2\\n\\
5989 \\t%(b\\t3f\\n\\
5990 \\tmove\\t%L0,%z4%)\\n\\
5991 \\n\\
5992 1:\\n\\
5993 \\t%(beq\\t%3,%z4,2f\\n\\
5994 \\tsll\\t%M0,%M1,%2%)\\n\\
5995 \\n\\
5996 \\tsubu\\t%3,%z4,%2\\n\\
5997 \\tsrl\\t%3,%L1,%3\\n\\
5998 \\tor\\t%M0,%M0,%3\\n\\
5999 2:\\n\\
6000 \\tsll\\t%L0,%L1,%2\\n\\
6001 3:\";
6002 }"
6003 [(set_attr "type" "darith")
6004 (set_attr "mode" "SI")
6005 (set_attr "length" "12")])
6006
6007
6008 (define_insn "ashldi3_internal2"
6009 [(set (match_operand:DI 0 "register_operand" "=d")
6010 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6011 (match_operand:SI 2 "small_int" "IJK")))
6012 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6013 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6014 && (INTVAL (operands[2]) & 32) != 0"
6015 "*
6016 {
6017 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6018 operands[4] = const0_rtx;
6019 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6020 }"
6021 [(set_attr "type" "darith")
6022 (set_attr "mode" "DI")
6023 (set_attr "length" "2")])
6024
6025
6026 (define_split
6027 [(set (match_operand:DI 0 "register_operand" "")
6028 (ashift:DI (match_operand:DI 1 "register_operand" "")
6029 (match_operand:SI 2 "small_int" "")))
6030 (clobber (match_operand:SI 3 "register_operand" ""))]
6031 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6032 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6033 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6034 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6035 && (INTVAL (operands[2]) & 32) != 0"
6036
6037 [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6038 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6039
6040 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6041
6042
6043 (define_split
6044 [(set (match_operand:DI 0 "register_operand" "")
6045 (ashift:DI (match_operand:DI 1 "register_operand" "")
6046 (match_operand:SI 2 "small_int" "")))
6047 (clobber (match_operand:SI 3 "register_operand" ""))]
6048 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6049 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6050 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6051 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6052 && (INTVAL (operands[2]) & 32) != 0"
6053
6054 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6055 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6056
6057 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6058
6059
6060 (define_insn "ashldi3_internal3"
6061 [(set (match_operand:DI 0 "register_operand" "=d")
6062 (ashift:DI (match_operand:DI 1 "register_operand" "d")
6063 (match_operand:SI 2 "small_int" "IJK")))
6064 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6065 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6066 && (INTVAL (operands[2]) & 63) < 32
6067 && (INTVAL (operands[2]) & 63) != 0"
6068 "*
6069 {
6070 int amount = INTVAL (operands[2]);
6071
6072 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6073 operands[4] = const0_rtx;
6074 operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6075
6076 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6077 }"
6078 [(set_attr "type" "darith")
6079 (set_attr "mode" "DI")
6080 (set_attr "length" "4")])
6081
6082
6083 (define_split
6084 [(set (match_operand:DI 0 "register_operand" "")
6085 (ashift:DI (match_operand:DI 1 "register_operand" "")
6086 (match_operand:SI 2 "small_int" "")))
6087 (clobber (match_operand:SI 3 "register_operand" ""))]
6088 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6089 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6090 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6091 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6092 && (INTVAL (operands[2]) & 63) < 32
6093 && (INTVAL (operands[2]) & 63) != 0"
6094
6095 [(set (subreg:SI (match_dup 0) 1)
6096 (ashift:SI (subreg:SI (match_dup 1) 1)
6097 (match_dup 2)))
6098
6099 (set (match_dup 3)
6100 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6101 (match_dup 4)))
6102
6103 (set (subreg:SI (match_dup 0) 1)
6104 (ior:SI (subreg:SI (match_dup 0) 1)
6105 (match_dup 3)))
6106
6107 (set (subreg:SI (match_dup 0) 0)
6108 (ashift:SI (subreg:SI (match_dup 1) 0)
6109 (match_dup 2)))]
6110 "
6111 {
6112 int amount = INTVAL (operands[2]);
6113 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6114 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6115 }")
6116
6117
6118 (define_split
6119 [(set (match_operand:DI 0 "register_operand" "")
6120 (ashift:DI (match_operand:DI 1 "register_operand" "")
6121 (match_operand:SI 2 "small_int" "")))
6122 (clobber (match_operand:SI 3 "register_operand" ""))]
6123 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6124 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6125 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6126 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6127 && (INTVAL (operands[2]) & 63) < 32
6128 && (INTVAL (operands[2]) & 63) != 0"
6129
6130 [(set (subreg:SI (match_dup 0) 0)
6131 (ashift:SI (subreg:SI (match_dup 1) 0)
6132 (match_dup 2)))
6133
6134 (set (match_dup 3)
6135 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6136 (match_dup 4)))
6137
6138 (set (subreg:SI (match_dup 0) 0)
6139 (ior:SI (subreg:SI (match_dup 0) 0)
6140 (match_dup 3)))
6141
6142 (set (subreg:SI (match_dup 0) 1)
6143 (ashift:SI (subreg:SI (match_dup 1) 1)
6144 (match_dup 2)))]
6145 "
6146 {
6147 int amount = INTVAL (operands[2]);
6148 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6149 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6150 }")
6151
6152
6153 (define_insn "ashldi3_internal4"
6154 [(set (match_operand:DI 0 "register_operand" "=d")
6155 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6156 (match_operand:SI 2 "arith_operand" "dI")))]
6157 "TARGET_64BIT && !TARGET_MIPS16"
6158 "*
6159 {
6160 if (GET_CODE (operands[2]) == CONST_INT)
6161 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6162
6163 return \"dsll\\t%0,%1,%2\";
6164 }"
6165 [(set_attr "type" "arith")
6166 (set_attr "mode" "DI")
6167 (set_attr "length" "1")])
6168
6169 (define_insn ""
6170 [(set (match_operand:DI 0 "register_operand" "=d,d")
6171 (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6172 (match_operand:SI 2 "arith_operand" "d,I")))]
6173 "TARGET_64BIT && TARGET_MIPS16"
6174 "*
6175 {
6176 if (which_alternative == 0)
6177 return \"dsll\\t%0,%2\";
6178
6179 if (GET_CODE (operands[2]) == CONST_INT)
6180 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6181
6182 return \"dsll\\t%0,%1,%2\";
6183 }"
6184 [(set_attr "type" "arith")
6185 (set_attr "mode" "DI")
6186 (set_attr_alternative "length"
6187 [(const_int 1)
6188 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6189 (const_int 1)
6190 (const_int 2))])])
6191
6192
6193 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6194
6195 (define_split
6196 [(set (match_operand:DI 0 "register_operand" "")
6197 (ashift:DI (match_operand:DI 1 "register_operand" "")
6198 (match_operand:SI 2 "const_int_operand" "")))]
6199 "TARGET_MIPS16 && TARGET_64BIT
6200 && reload_completed
6201 && GET_CODE (operands[2]) == CONST_INT
6202 && INTVAL (operands[2]) > 8
6203 && INTVAL (operands[2]) <= 16"
6204 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6205 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6206 "
6207 {
6208 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6209 }")
6210
6211 (define_expand "ashrsi3"
6212 [(set (match_operand:SI 0 "register_operand" "=d")
6213 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6214 (match_operand:SI 2 "arith_operand" "dI")))]
6215 ""
6216 "
6217 {
6218 /* On the mips16, a shift of more than 8 is a four byte instruction,
6219 so, for a shift between 8 and 16, it is just as fast to do two
6220 shifts of 8 or less. If there is a lot of shifting going on, we
6221 may win in CSE. Otherwise combine will put the shifts back
6222 together again. */
6223 if (TARGET_MIPS16
6224 && optimize
6225 && GET_CODE (operands[2]) == CONST_INT
6226 && INTVAL (operands[2]) > 8
6227 && INTVAL (operands[2]) <= 16)
6228 {
6229 rtx temp = gen_reg_rtx (SImode);
6230
6231 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6232 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6233 GEN_INT (INTVAL (operands[2]) - 8)));
6234 DONE;
6235 }
6236 }")
6237
6238 (define_insn "ashrsi3_internal1"
6239 [(set (match_operand:SI 0 "register_operand" "=d")
6240 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6241 (match_operand:SI 2 "arith_operand" "dI")))]
6242 "!TARGET_MIPS16"
6243 "*
6244 {
6245 if (GET_CODE (operands[2]) == CONST_INT)
6246 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6247
6248 return \"sra\\t%0,%1,%2\";
6249 }"
6250 [(set_attr "type" "arith")
6251 (set_attr "mode" "SI")
6252 (set_attr "length" "1")])
6253
6254 (define_insn "ashrsi3_internal2"
6255 [(set (match_operand:SI 0 "register_operand" "=d,d")
6256 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6257 (match_operand:SI 2 "arith_operand" "d,I")))]
6258 "TARGET_MIPS16"
6259 "*
6260 {
6261 if (which_alternative == 0)
6262 return \"sra\\t%0,%2\";
6263
6264 if (GET_CODE (operands[2]) == CONST_INT)
6265 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6266
6267 return \"sra\\t%0,%1,%2\";
6268 }"
6269 [(set_attr "type" "arith")
6270 (set_attr "mode" "SI")
6271 (set_attr_alternative "length"
6272 [(const_int 1)
6273 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6274 (const_int 1)
6275 (const_int 2))])])
6276
6277
6278 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6279
6280 (define_split
6281 [(set (match_operand:SI 0 "register_operand" "")
6282 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6283 (match_operand:SI 2 "const_int_operand" "")))]
6284 "TARGET_MIPS16
6285 && reload_completed
6286 && GET_CODE (operands[2]) == CONST_INT
6287 && INTVAL (operands[2]) > 8
6288 && INTVAL (operands[2]) <= 16"
6289 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6290 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6291 "
6292 {
6293 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6294 }")
6295
6296 (define_expand "ashrdi3"
6297 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6298 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6299 (match_operand:SI 2 "arith_operand" "")))
6300 (clobber (match_dup 3))])]
6301 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6302 "
6303 {
6304 if (TARGET_64BIT)
6305 {
6306 /* On the mips16, a shift of more than 8 is a four byte
6307 instruction, so, for a shift between 8 and 16, it is just as
6308 fast to do two shifts of 8 or less. If there is a lot of
6309 shifting going on, we may win in CSE. Otherwise combine will
6310 put the shifts back together again. */
6311 if (TARGET_MIPS16
6312 && optimize
6313 && GET_CODE (operands[2]) == CONST_INT
6314 && INTVAL (operands[2]) > 8
6315 && INTVAL (operands[2]) <= 16)
6316 {
6317 rtx temp = gen_reg_rtx (DImode);
6318
6319 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6320 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6321 GEN_INT (INTVAL (operands[2]) - 8)));
6322 DONE;
6323 }
6324
6325 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6326 operands[2]));
6327 DONE;
6328 }
6329
6330 operands[3] = gen_reg_rtx (SImode);
6331 }")
6332
6333
6334 (define_insn "ashrdi3_internal"
6335 [(set (match_operand:DI 0 "register_operand" "=&d")
6336 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6337 (match_operand:SI 2 "register_operand" "d")))
6338 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6339 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6340 "*
6341 {
6342 operands[4] = const0_rtx;
6343 dslots_jump_total += 3;
6344 dslots_jump_filled += 2;
6345
6346 return \"sll\\t%3,%2,26\\n\\
6347 \\tbgez\\t%3,1f\\n\\
6348 \\tsra\\t%L0,%M1,%2\\n\\
6349 \\t%(b\\t3f\\n\\
6350 \\tsra\\t%M0,%M1,31%)\\n\\
6351 \\n\\
6352 1:\\n\\
6353 \\t%(beq\\t%3,%z4,2f\\n\\
6354 \\tsrl\\t%L0,%L1,%2%)\\n\\
6355 \\n\\
6356 \\tsubu\\t%3,%z4,%2\\n\\
6357 \\tsll\\t%3,%M1,%3\\n\\
6358 \\tor\\t%L0,%L0,%3\\n\\
6359 2:\\n\\
6360 \\tsra\\t%M0,%M1,%2\\n\\
6361 3:\";
6362 }"
6363 [(set_attr "type" "darith")
6364 (set_attr "mode" "DI")
6365 (set_attr "length" "12")])
6366
6367
6368 (define_insn "ashrdi3_internal2"
6369 [(set (match_operand:DI 0 "register_operand" "=d")
6370 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6371 (match_operand:SI 2 "small_int" "IJK")))
6372 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6373 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
6374 "*
6375 {
6376 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6377 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6378 }"
6379 [(set_attr "type" "darith")
6380 (set_attr "mode" "DI")
6381 (set_attr "length" "2")])
6382
6383
6384 (define_split
6385 [(set (match_operand:DI 0 "register_operand" "")
6386 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6387 (match_operand:SI 2 "small_int" "")))
6388 (clobber (match_operand:SI 3 "register_operand" ""))]
6389 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6390 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6391 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6392 && (INTVAL (operands[2]) & 32) != 0"
6393
6394 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6395 (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
6396
6397 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6398
6399
6400 (define_split
6401 [(set (match_operand:DI 0 "register_operand" "")
6402 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6403 (match_operand:SI 2 "small_int" "")))
6404 (clobber (match_operand:SI 3 "register_operand" ""))]
6405 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6406 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6407 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6408 && (INTVAL (operands[2]) & 32) != 0"
6409
6410 [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6411 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6412
6413 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6414
6415
6416 (define_insn "ashrdi3_internal3"
6417 [(set (match_operand:DI 0 "register_operand" "=d")
6418 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6419 (match_operand:SI 2 "small_int" "IJK")))
6420 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6421 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6422 && (INTVAL (operands[2]) & 63) < 32
6423 && (INTVAL (operands[2]) & 63) != 0"
6424 "*
6425 {
6426 int amount = INTVAL (operands[2]);
6427
6428 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6429 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6430
6431 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
6432 }"
6433 [(set_attr "type" "darith")
6434 (set_attr "mode" "DI")
6435 (set_attr "length" "4")])
6436
6437
6438 (define_split
6439 [(set (match_operand:DI 0 "register_operand" "")
6440 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6441 (match_operand:SI 2 "small_int" "")))
6442 (clobber (match_operand:SI 3 "register_operand" ""))]
6443 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6444 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6445 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6446 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6447 && (INTVAL (operands[2]) & 63) < 32
6448 && (INTVAL (operands[2]) & 63) != 0"
6449
6450 [(set (subreg:SI (match_dup 0) 0)
6451 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6452 (match_dup 2)))
6453
6454 (set (match_dup 3)
6455 (ashift:SI (subreg:SI (match_dup 1) 1)
6456 (match_dup 4)))
6457
6458 (set (subreg:SI (match_dup 0) 0)
6459 (ior:SI (subreg:SI (match_dup 0) 0)
6460 (match_dup 3)))
6461
6462 (set (subreg:SI (match_dup 0) 1)
6463 (ashiftrt:SI (subreg:SI (match_dup 1) 1)
6464 (match_dup 2)))]
6465 "
6466 {
6467 int amount = INTVAL (operands[2]);
6468 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6469 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6470 }")
6471
6472
6473 (define_split
6474 [(set (match_operand:DI 0 "register_operand" "")
6475 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6476 (match_operand:SI 2 "small_int" "")))
6477 (clobber (match_operand:SI 3 "register_operand" ""))]
6478 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6479 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6480 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6481 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6482 && (INTVAL (operands[2]) & 63) < 32
6483 && (INTVAL (operands[2]) & 63) != 0"
6484
6485 [(set (subreg:SI (match_dup 0) 1)
6486 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6487 (match_dup 2)))
6488
6489 (set (match_dup 3)
6490 (ashift:SI (subreg:SI (match_dup 1) 0)
6491 (match_dup 4)))
6492
6493 (set (subreg:SI (match_dup 0) 1)
6494 (ior:SI (subreg:SI (match_dup 0) 1)
6495 (match_dup 3)))
6496
6497 (set (subreg:SI (match_dup 0) 0)
6498 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
6499 (match_dup 2)))]
6500 "
6501 {
6502 int amount = INTVAL (operands[2]);
6503 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6504 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6505 }")
6506
6507
6508 (define_insn "ashrdi3_internal4"
6509 [(set (match_operand:DI 0 "register_operand" "=d")
6510 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6511 (match_operand:SI 2 "arith_operand" "dI")))]
6512 "TARGET_64BIT && !TARGET_MIPS16"
6513 "*
6514 {
6515 if (GET_CODE (operands[2]) == CONST_INT)
6516 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6517
6518 return \"dsra\\t%0,%1,%2\";
6519 }"
6520 [(set_attr "type" "arith")
6521 (set_attr "mode" "DI")
6522 (set_attr "length" "1")])
6523
6524 (define_insn ""
6525 [(set (match_operand:DI 0 "register_operand" "=d,d")
6526 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
6527 (match_operand:SI 2 "arith_operand" "d,I")))]
6528 "TARGET_64BIT && TARGET_MIPS16"
6529 "*
6530 {
6531 if (GET_CODE (operands[2]) == CONST_INT)
6532 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6533
6534 return \"dsra\\t%0,%2\";
6535 }"
6536 [(set_attr "type" "arith")
6537 (set_attr "mode" "DI")
6538 (set_attr_alternative "length"
6539 [(const_int 1)
6540 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6541 (const_int 1)
6542 (const_int 2))])])
6543
6544 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6545
6546 (define_split
6547 [(set (match_operand:DI 0 "register_operand" "")
6548 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6549 (match_operand:SI 2 "const_int_operand" "")))]
6550 "TARGET_MIPS16 && TARGET_64BIT
6551 && reload_completed
6552 && GET_CODE (operands[2]) == CONST_INT
6553 && INTVAL (operands[2]) > 8
6554 && INTVAL (operands[2]) <= 16"
6555 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
6556 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
6557 "
6558 {
6559 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6560 }")
6561
6562 (define_expand "lshrsi3"
6563 [(set (match_operand:SI 0 "register_operand" "=d")
6564 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
6565 (match_operand:SI 2 "arith_operand" "dI")))]
6566 ""
6567 "
6568 {
6569 /* On the mips16, a shift of more than 8 is a four byte instruction,
6570 so, for a shift between 8 and 16, it is just as fast to do two
6571 shifts of 8 or less. If there is a lot of shifting going on, we
6572 may win in CSE. Otherwise combine will put the shifts back
6573 together again. */
6574 if (TARGET_MIPS16
6575 && optimize
6576 && GET_CODE (operands[2]) == CONST_INT
6577 && INTVAL (operands[2]) > 8
6578 && INTVAL (operands[2]) <= 16)
6579 {
6580 rtx temp = gen_reg_rtx (SImode);
6581
6582 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6583 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
6584 GEN_INT (INTVAL (operands[2]) - 8)));
6585 DONE;
6586 }
6587 }")
6588
6589 (define_insn "lshrsi3_internal1"
6590 [(set (match_operand:SI 0 "register_operand" "=d")
6591 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
6592 (match_operand:SI 2 "arith_operand" "dI")))]
6593 "!TARGET_MIPS16"
6594 "*
6595 {
6596 if (GET_CODE (operands[2]) == CONST_INT)
6597 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6598
6599 return \"srl\\t%0,%1,%2\";
6600 }"
6601 [(set_attr "type" "arith")
6602 (set_attr "mode" "SI")
6603 (set_attr "length" "1")])
6604
6605 (define_insn "lshrsi3_internal2"
6606 [(set (match_operand:SI 0 "register_operand" "=d,d")
6607 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6608 (match_operand:SI 2 "arith_operand" "d,I")))]
6609 "TARGET_MIPS16"
6610 "*
6611 {
6612 if (which_alternative == 0)
6613 return \"srl\\t%0,%2\";
6614
6615 if (GET_CODE (operands[2]) == CONST_INT)
6616 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6617
6618 return \"srl\\t%0,%1,%2\";
6619 }"
6620 [(set_attr "type" "arith")
6621 (set_attr "mode" "SI")
6622 (set_attr_alternative "length"
6623 [(const_int 1)
6624 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6625 (const_int 1)
6626 (const_int 2))])])
6627
6628
6629 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6630
6631 (define_split
6632 [(set (match_operand:SI 0 "register_operand" "")
6633 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
6634 (match_operand:SI 2 "const_int_operand" "")))]
6635 "TARGET_MIPS16
6636 && reload_completed
6637 && GET_CODE (operands[2]) == CONST_INT
6638 && INTVAL (operands[2]) > 8
6639 && INTVAL (operands[2]) <= 16"
6640 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
6641 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
6642 "
6643 {
6644 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6645 }")
6646
6647 ;; If we load a byte on the mips16 as a bitfield, the resulting
6648 ;; sequence of instructions is too complicated for combine, because it
6649 ;; involves four instructions: a load, a shift, a constant load into a
6650 ;; register, and an and (the key problem here is that the mips16 does
6651 ;; not have and immediate). We recognize a shift of a load in order
6652 ;; to make it simple enough for combine to understand.
6653
6654 (define_insn ""
6655 [(set (match_operand:SI 0 "register_operand" "d,d")
6656 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
6657 (match_operand:SI 2 "immediate_operand" "I,I")))]
6658 "TARGET_MIPS16"
6659 "lw\\t%0,%1\;srl\\t%0,%2"
6660 [(set_attr "type" "load")
6661 (set_attr "mode" "SI")
6662 (set_attr_alternative "length"
6663 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6664 (const_int 2)
6665 (const_int 3))
6666 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6667 (const_int 3)
6668 (const_int 4))])])
6669
6670 (define_split
6671 [(set (match_operand:SI 0 "register_operand" "")
6672 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
6673 (match_operand:SI 2 "immediate_operand" "")))]
6674 "TARGET_MIPS16"
6675 [(set (match_dup 0) (match_dup 1))
6676 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
6677 "")
6678
6679 (define_expand "lshrdi3"
6680 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6681 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6682 (match_operand:SI 2 "arith_operand" "")))
6683 (clobber (match_dup 3))])]
6684 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6685 "
6686 {
6687 if (TARGET_64BIT)
6688 {
6689 /* On the mips16, a shift of more than 8 is a four byte
6690 instruction, so, for a shift between 8 and 16, it is just as
6691 fast to do two shifts of 8 or less. If there is a lot of
6692 shifting going on, we may win in CSE. Otherwise combine will
6693 put the shifts back together again. */
6694 if (TARGET_MIPS16
6695 && optimize
6696 && GET_CODE (operands[2]) == CONST_INT
6697 && INTVAL (operands[2]) > 8
6698 && INTVAL (operands[2]) <= 16)
6699 {
6700 rtx temp = gen_reg_rtx (DImode);
6701
6702 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6703 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
6704 GEN_INT (INTVAL (operands[2]) - 8)));
6705 DONE;
6706 }
6707
6708 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
6709 operands[2]));
6710 DONE;
6711 }
6712
6713 operands[3] = gen_reg_rtx (SImode);
6714 }")
6715
6716
6717 (define_insn "lshrdi3_internal"
6718 [(set (match_operand:DI 0 "register_operand" "=&d")
6719 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6720 (match_operand:SI 2 "register_operand" "d")))
6721 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6722 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6723 "*
6724 {
6725 operands[4] = const0_rtx;
6726 dslots_jump_total += 3;
6727 dslots_jump_filled += 2;
6728
6729 return \"sll\\t%3,%2,26\\n\\
6730 \\tbgez\\t%3,1f\\n\\
6731 \\tsrl\\t%L0,%M1,%2\\n\\
6732 \\t%(b\\t3f\\n\\
6733 \\tmove\\t%M0,%z4%)\\n\\
6734 \\n\\
6735 1:\\n\\
6736 \\t%(beq\\t%3,%z4,2f\\n\\
6737 \\tsrl\\t%L0,%L1,%2%)\\n\\
6738 \\n\\
6739 \\tsubu\\t%3,%z4,%2\\n\\
6740 \\tsll\\t%3,%M1,%3\\n\\
6741 \\tor\\t%L0,%L0,%3\\n\\
6742 2:\\n\\
6743 \\tsrl\\t%M0,%M1,%2\\n\\
6744 3:\";
6745 }"
6746 [(set_attr "type" "darith")
6747 (set_attr "mode" "DI")
6748 (set_attr "length" "12")])
6749
6750
6751 (define_insn "lshrdi3_internal2"
6752 [(set (match_operand:DI 0 "register_operand" "=d")
6753 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6754 (match_operand:SI 2 "small_int" "IJK")))
6755 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6756 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6757 && (INTVAL (operands[2]) & 32) != 0"
6758 "*
6759 {
6760 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6761 operands[4] = const0_rtx;
6762 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
6763 }"
6764 [(set_attr "type" "darith")
6765 (set_attr "mode" "DI")
6766 (set_attr "length" "2")])
6767
6768
6769 (define_split
6770 [(set (match_operand:DI 0 "register_operand" "")
6771 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6772 (match_operand:SI 2 "small_int" "")))
6773 (clobber (match_operand:SI 3 "register_operand" ""))]
6774 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6775 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6776 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6777 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6778 && (INTVAL (operands[2]) & 32) != 0"
6779
6780 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6781 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6782
6783 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6784
6785
6786 (define_split
6787 [(set (match_operand:DI 0 "register_operand" "")
6788 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6789 (match_operand:SI 2 "small_int" "")))
6790 (clobber (match_operand:SI 3 "register_operand" ""))]
6791 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6792 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6793 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6794 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6795 && (INTVAL (operands[2]) & 32) != 0"
6796
6797 [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6798 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6799
6800 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6801
6802
6803 (define_insn "lshrdi3_internal3"
6804 [(set (match_operand:DI 0 "register_operand" "=d")
6805 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6806 (match_operand:SI 2 "small_int" "IJK")))
6807 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6808 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6809 && (INTVAL (operands[2]) & 63) < 32
6810 && (INTVAL (operands[2]) & 63) != 0"
6811 "*
6812 {
6813 int amount = INTVAL (operands[2]);
6814
6815 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6816 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6817
6818 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
6819 }"
6820 [(set_attr "type" "darith")
6821 (set_attr "mode" "DI")
6822 (set_attr "length" "4")])
6823
6824
6825 (define_split
6826 [(set (match_operand:DI 0 "register_operand" "")
6827 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6828 (match_operand:SI 2 "small_int" "")))
6829 (clobber (match_operand:SI 3 "register_operand" ""))]
6830 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6831 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6832 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6833 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6834 && (INTVAL (operands[2]) & 63) < 32
6835 && (INTVAL (operands[2]) & 63) != 0"
6836
6837 [(set (subreg:SI (match_dup 0) 0)
6838 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6839 (match_dup 2)))
6840
6841 (set (match_dup 3)
6842 (ashift:SI (subreg:SI (match_dup 1) 1)
6843 (match_dup 4)))
6844
6845 (set (subreg:SI (match_dup 0) 0)
6846 (ior:SI (subreg:SI (match_dup 0) 0)
6847 (match_dup 3)))
6848
6849 (set (subreg:SI (match_dup 0) 1)
6850 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6851 (match_dup 2)))]
6852 "
6853 {
6854 int amount = INTVAL (operands[2]);
6855 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6856 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6857 }")
6858
6859
6860 (define_split
6861 [(set (match_operand:DI 0 "register_operand" "")
6862 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6863 (match_operand:SI 2 "small_int" "")))
6864 (clobber (match_operand:SI 3 "register_operand" ""))]
6865 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6866 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6867 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6868 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6869 && (INTVAL (operands[2]) & 63) < 32
6870 && (INTVAL (operands[2]) & 63) != 0"
6871
6872 [(set (subreg:SI (match_dup 0) 1)
6873 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6874 (match_dup 2)))
6875
6876 (set (match_dup 3)
6877 (ashift:SI (subreg:SI (match_dup 1) 0)
6878 (match_dup 4)))
6879
6880 (set (subreg:SI (match_dup 0) 1)
6881 (ior:SI (subreg:SI (match_dup 0) 1)
6882 (match_dup 3)))
6883
6884 (set (subreg:SI (match_dup 0) 0)
6885 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6886 (match_dup 2)))]
6887 "
6888 {
6889 int amount = INTVAL (operands[2]);
6890 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6891 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6892 }")
6893
6894
6895 (define_insn "lshrdi3_internal4"
6896 [(set (match_operand:DI 0 "register_operand" "=d")
6897 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6898 (match_operand:SI 2 "arith_operand" "dI")))]
6899 "TARGET_64BIT && !TARGET_MIPS16"
6900 "*
6901 {
6902 if (GET_CODE (operands[2]) == CONST_INT)
6903 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6904
6905 return \"dsrl\\t%0,%1,%2\";
6906 }"
6907 [(set_attr "type" "arith")
6908 (set_attr "mode" "DI")
6909 (set_attr "length" "1")])
6910
6911 (define_insn ""
6912 [(set (match_operand:DI 0 "register_operand" "=d,d")
6913 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
6914 (match_operand:SI 2 "arith_operand" "d,I")))]
6915 "TARGET_64BIT && TARGET_MIPS16"
6916 "*
6917 {
6918 if (GET_CODE (operands[2]) == CONST_INT)
6919 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6920
6921 return \"dsrl\\t%0,%2\";
6922 }"
6923 [(set_attr "type" "arith")
6924 (set_attr "mode" "DI")
6925 (set_attr_alternative "length"
6926 [(const_int 1)
6927 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6928 (const_int 1)
6929 (const_int 2))])])
6930
6931 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6932
6933 (define_split
6934 [(set (match_operand:DI 0 "register_operand" "")
6935 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6936 (match_operand:SI 2 "const_int_operand" "")))]
6937 "TARGET_MIPS16
6938 && reload_completed
6939 && GET_CODE (operands[2]) == CONST_INT
6940 && INTVAL (operands[2]) > 8
6941 && INTVAL (operands[2]) <= 16"
6942 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
6943 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
6944 "
6945 {
6946 operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6947 }")
6948
6949 \f
6950 ;;
6951 ;; ....................
6952 ;;
6953 ;; COMPARISONS
6954 ;;
6955 ;; ....................
6956
6957 ;; Flow here is rather complex:
6958 ;;
6959 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
6960 ;; arguments into the branch_cmp array, and the type into
6961 ;; branch_type. No RTL is generated.
6962 ;;
6963 ;; 2) The appropriate branch define_expand is called, which then
6964 ;; creates the appropriate RTL for the comparison and branch.
6965 ;; Different CC modes are used, based on what type of branch is
6966 ;; done, so that we can constrain things appropriately. There
6967 ;; are assumptions in the rest of GCC that break if we fold the
6968 ;; operands into the branchs for integer operations, and use cc0
6969 ;; for floating point, so we use the fp status register instead.
6970 ;; If needed, an appropriate temporary is created to hold the
6971 ;; of the integer compare.
6972
6973 (define_expand "cmpsi"
6974 [(set (cc0)
6975 (compare:CC (match_operand:SI 0 "register_operand" "")
6976 (match_operand:SI 1 "arith_operand" "")))]
6977 ""
6978 "
6979 {
6980 if (operands[0]) /* avoid unused code message */
6981 {
6982 branch_cmp[0] = operands[0];
6983 branch_cmp[1] = operands[1];
6984 branch_type = CMP_SI;
6985 DONE;
6986 }
6987 }")
6988
6989 (define_expand "tstsi"
6990 [(set (cc0)
6991 (match_operand:SI 0 "register_operand" ""))]
6992 ""
6993 "
6994 {
6995 if (operands[0]) /* avoid unused code message */
6996 {
6997 branch_cmp[0] = operands[0];
6998 branch_cmp[1] = const0_rtx;
6999 branch_type = CMP_SI;
7000 DONE;
7001 }
7002 }")
7003
7004 (define_expand "cmpdi"
7005 [(set (cc0)
7006 (compare:CC (match_operand:DI 0 "se_register_operand" "")
7007 (match_operand:DI 1 "se_arith_operand" "")))]
7008 "TARGET_64BIT"
7009 "
7010 {
7011 if (operands[0]) /* avoid unused code message */
7012 {
7013 branch_cmp[0] = operands[0];
7014 branch_cmp[1] = operands[1];
7015 branch_type = CMP_DI;
7016 DONE;
7017 }
7018 }")
7019
7020 (define_expand "tstdi"
7021 [(set (cc0)
7022 (match_operand:DI 0 "se_register_operand" ""))]
7023 "TARGET_64BIT"
7024 "
7025 {
7026 if (operands[0]) /* avoid unused code message */
7027 {
7028 branch_cmp[0] = operands[0];
7029 branch_cmp[1] = const0_rtx;
7030 branch_type = CMP_DI;
7031 DONE;
7032 }
7033 }")
7034
7035 (define_expand "cmpdf"
7036 [(set (cc0)
7037 (compare:CC (match_operand:DF 0 "register_operand" "")
7038 (match_operand:DF 1 "register_operand" "")))]
7039 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7040 "
7041 {
7042 if (operands[0]) /* avoid unused code message */
7043 {
7044 branch_cmp[0] = operands[0];
7045 branch_cmp[1] = operands[1];
7046 branch_type = CMP_DF;
7047 DONE;
7048 }
7049 }")
7050
7051 (define_expand "cmpsf"
7052 [(set (cc0)
7053 (compare:CC (match_operand:SF 0 "register_operand" "")
7054 (match_operand:SF 1 "register_operand" "")))]
7055 "TARGET_HARD_FLOAT"
7056 "
7057 {
7058 if (operands[0]) /* avoid unused code message */
7059 {
7060 branch_cmp[0] = operands[0];
7061 branch_cmp[1] = operands[1];
7062 branch_type = CMP_SF;
7063 DONE;
7064 }
7065 }")
7066
7067 \f
7068 ;;
7069 ;; ....................
7070 ;;
7071 ;; CONDITIONAL BRANCHES
7072 ;;
7073 ;; ....................
7074
7075 (define_insn "branch_fp_ne"
7076 [(set (pc)
7077 (if_then_else (ne:CC (match_operand:CC 0 "register_operand" "z")
7078 (const_int 0))
7079 (match_operand 1 "pc_or_label_operand" "")
7080 (match_operand 2 "pc_or_label_operand" "")))]
7081 "TARGET_HARD_FLOAT"
7082 "*
7083 {
7084 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7085 return (operands[1] != pc_rtx) ? \"%*bc1t%?\\t%Z0%1\" : \"%*bc1f%?\\t%Z0%2\";
7086 }"
7087 [(set_attr "type" "branch")
7088 (set_attr "mode" "none")
7089 (set_attr "length" "1")])
7090
7091 (define_insn "branch_fp_eq"
7092 [(set (pc)
7093 (if_then_else (eq:CC (match_operand:CC 0 "register_operand" "z")
7094 (const_int 0))
7095 (match_operand 1 "pc_or_label_operand" "")
7096 (match_operand 2 "pc_or_label_operand" "")))]
7097 "TARGET_HARD_FLOAT"
7098 "*
7099 {
7100 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7101 return (operands[1] != pc_rtx) ? \"%*bc1f%?\\t%Z0%1\" : \"%*bc1t%?\\t%Z0%2\";
7102 }"
7103 [(set_attr "type" "branch")
7104 (set_attr "mode" "none")
7105 (set_attr "length" "1")])
7106
7107 (define_insn "branch_zero"
7108 [(set (pc)
7109 (if_then_else (match_operator:SI 0 "cmp_op"
7110 [(match_operand:SI 1 "register_operand" "d")
7111 (const_int 0)])
7112 (match_operand 2 "pc_or_label_operand" "")
7113 (match_operand 3 "pc_or_label_operand" "")))]
7114 "!TARGET_MIPS16"
7115 "*
7116 {
7117 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7118 if (operands[2] != pc_rtx)
7119 { /* normal jump */
7120 switch (GET_CODE (operands[0]))
7121 {
7122 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
7123 case NE: return \"%*bne%?\\t%z1,%.,%2\";
7124 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
7125 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
7126 case GEU: return \"%*j\\t%2\";
7127 case LTU: return \"%*bne%?\\t%.,%.,%2\";
7128 }
7129
7130 return \"%*b%C0z%?\\t%z1,%2\";
7131 }
7132 else
7133 { /* inverted jump */
7134 switch (GET_CODE (operands[0]))
7135 {
7136 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
7137 case NE: return \"%*beq%?\\t%z1,%.,%3\";
7138 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
7139 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
7140 case GEU: return \"%*beq%?\\t%.,%.,%3\";
7141 case LTU: return \"%*j\\t%3\";
7142 }
7143
7144 return \"%*b%N0z%?\\t%z1,%3\";
7145 }
7146 }"
7147 [(set_attr "type" "branch")
7148 (set_attr "mode" "none")
7149 (set_attr "length" "1")])
7150
7151
7152 (define_insn ""
7153 [(set (pc)
7154 (if_then_else (match_operator:SI 0 "equality_op"
7155 [(match_operand:SI 1 "register_operand" "d,t")
7156 (const_int 0)])
7157 (match_operand 2 "pc_or_label_operand" "")
7158 (match_operand 3 "pc_or_label_operand" "")))]
7159 "TARGET_MIPS16"
7160 "*
7161 {
7162 if (operands[2] != pc_rtx)
7163 {
7164 if (which_alternative == 0)
7165 return \"%*b%C0z\\t%1,%2\";
7166 else
7167 return \"%*bt%C0z\\t%2\";
7168 }
7169 else
7170 {
7171 if (which_alternative == 0)
7172 return \"%*b%N0z\\t%1,%3\";
7173 else
7174 return \"%*bt%N0z\\t%3\";
7175 }
7176 }"
7177 [(set_attr "type" "branch")
7178 (set_attr "mode" "none")
7179 (set_attr "length" "2")])
7180
7181 (define_insn "branch_zero_di"
7182 [(set (pc)
7183 (if_then_else (match_operator:DI 0 "cmp_op"
7184 [(match_operand:DI 1 "se_register_operand" "d")
7185 (const_int 0)])
7186 (match_operand 2 "pc_or_label_operand" "")
7187 (match_operand 3 "pc_or_label_operand" "")))]
7188 "!TARGET_MIPS16"
7189 "*
7190 {
7191 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7192 if (operands[2] != pc_rtx)
7193 { /* normal jump */
7194 switch (GET_CODE (operands[0]))
7195 {
7196 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
7197 case NE: return \"%*bne%?\\t%z1,%.,%2\";
7198 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
7199 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
7200 case GEU: return \"%*j\\t%2\";
7201 case LTU: return \"%*bne%?\\t%.,%.,%2\";
7202 }
7203
7204 return \"%*b%C0z%?\\t%z1,%2\";
7205 }
7206 else
7207 { /* inverted jump */
7208 switch (GET_CODE (operands[0]))
7209 {
7210 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
7211 case NE: return \"%*beq%?\\t%z1,%.,%3\";
7212 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
7213 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
7214 case GEU: return \"%*beq%?\\t%.,%.,%3\";
7215 case LTU: return \"%*j\\t%3\";
7216 }
7217
7218 return \"%*b%N0z%?\\t%z1,%3\";
7219 }
7220 }"
7221 [(set_attr "type" "branch")
7222 (set_attr "mode" "none")
7223 (set_attr "length" "1")])
7224
7225 (define_insn ""
7226 [(set (pc)
7227 (if_then_else (match_operator:DI 0 "equality_op"
7228 [(match_operand:DI 1 "se_register_operand" "d,t")
7229 (const_int 0)])
7230 (match_operand 2 "pc_or_label_operand" "")
7231 (match_operand 3 "pc_or_label_operand" "")))]
7232 "TARGET_MIPS16"
7233 "*
7234 {
7235 if (operands[2] != pc_rtx)
7236 {
7237 if (which_alternative == 0)
7238 return \"%*b%C0z\\t%1,%2\";
7239 else
7240 return \"%*bt%C0z\\t%2\";
7241 }
7242 else
7243 {
7244 if (which_alternative == 0)
7245 return \"%*b%N0z\\t%1,%3\";
7246 else
7247 return \"%*bt%N0z\\t%3\";
7248 }
7249 }"
7250 [(set_attr "type" "branch")
7251 (set_attr "mode" "none")
7252 (set_attr "length" "2")])
7253
7254
7255 (define_insn "branch_equality"
7256 [(set (pc)
7257 (if_then_else (match_operator:SI 0 "equality_op"
7258 [(match_operand:SI 1 "register_operand" "d")
7259 (match_operand:SI 2 "register_operand" "d")])
7260 (match_operand 3 "pc_or_label_operand" "")
7261 (match_operand 4 "pc_or_label_operand" "")))]
7262 "!TARGET_MIPS16"
7263 "*
7264 {
7265 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7266 return (operands[3] != pc_rtx)
7267 ? \"%*b%C0%?\\t%z1,%z2,%3\"
7268 : \"%*b%N0%?\\t%z1,%z2,%4\";
7269 }"
7270 [(set_attr "type" "branch")
7271 (set_attr "mode" "none")
7272 (set_attr "length" "1")])
7273
7274
7275 (define_insn "branch_equality_di"
7276 [(set (pc)
7277 (if_then_else (match_operator:DI 0 "equality_op"
7278 [(match_operand:DI 1 "se_register_operand" "d")
7279 (match_operand:DI 2 "se_register_operand" "d")])
7280 (match_operand 3 "pc_or_label_operand" "")
7281 (match_operand 4 "pc_or_label_operand" "")))]
7282 "!TARGET_MIPS16"
7283 "*
7284 {
7285 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7286 return (operands[3] != pc_rtx)
7287 ? \"%*b%C0%?\\t%z1,%z2,%3\"
7288 : \"%*b%N0%?\\t%z1,%z2,%4\";
7289 }"
7290 [(set_attr "type" "branch")
7291 (set_attr "mode" "none")
7292 (set_attr "length" "1")])
7293
7294
7295 (define_expand "beq"
7296 [(set (pc)
7297 (if_then_else (eq:CC (cc0)
7298 (const_int 0))
7299 (label_ref (match_operand 0 "" ""))
7300 (pc)))]
7301 ""
7302 "
7303 {
7304 if (operands[0]) /* avoid unused code warning */
7305 {
7306 gen_conditional_branch (operands, EQ);
7307 DONE;
7308 }
7309 }")
7310
7311 (define_expand "bne"
7312 [(set (pc)
7313 (if_then_else (ne:CC (cc0)
7314 (const_int 0))
7315 (label_ref (match_operand 0 "" ""))
7316 (pc)))]
7317 ""
7318 "
7319 {
7320 if (operands[0]) /* avoid unused code warning */
7321 {
7322 gen_conditional_branch (operands, NE);
7323 DONE;
7324 }
7325 }")
7326
7327 (define_expand "bgt"
7328 [(set (pc)
7329 (if_then_else (gt:CC (cc0)
7330 (const_int 0))
7331 (label_ref (match_operand 0 "" ""))
7332 (pc)))]
7333 ""
7334 "
7335 {
7336 if (operands[0]) /* avoid unused code warning */
7337 {
7338 gen_conditional_branch (operands, GT);
7339 DONE;
7340 }
7341 }")
7342
7343 (define_expand "bge"
7344 [(set (pc)
7345 (if_then_else (ge:CC (cc0)
7346 (const_int 0))
7347 (label_ref (match_operand 0 "" ""))
7348 (pc)))]
7349 ""
7350 "
7351 {
7352 if (operands[0]) /* avoid unused code warning */
7353 {
7354 gen_conditional_branch (operands, GE);
7355 DONE;
7356 }
7357 }")
7358
7359 (define_expand "blt"
7360 [(set (pc)
7361 (if_then_else (lt:CC (cc0)
7362 (const_int 0))
7363 (label_ref (match_operand 0 "" ""))
7364 (pc)))]
7365 ""
7366 "
7367 {
7368 if (operands[0]) /* avoid unused code warning */
7369 {
7370 gen_conditional_branch (operands, LT);
7371 DONE;
7372 }
7373 }")
7374
7375 (define_expand "ble"
7376 [(set (pc)
7377 (if_then_else (le:CC (cc0)
7378 (const_int 0))
7379 (label_ref (match_operand 0 "" ""))
7380 (pc)))]
7381 ""
7382 "
7383 {
7384 if (operands[0]) /* avoid unused code warning */
7385 {
7386 gen_conditional_branch (operands, LE);
7387 DONE;
7388 }
7389 }")
7390
7391 (define_expand "bgtu"
7392 [(set (pc)
7393 (if_then_else (gtu:CC (cc0)
7394 (const_int 0))
7395 (label_ref (match_operand 0 "" ""))
7396 (pc)))]
7397 ""
7398 "
7399 {
7400 if (operands[0]) /* avoid unused code warning */
7401 {
7402 gen_conditional_branch (operands, GTU);
7403 DONE;
7404 }
7405 }")
7406
7407 (define_expand "bgeu"
7408 [(set (pc)
7409 (if_then_else (geu:CC (cc0)
7410 (const_int 0))
7411 (label_ref (match_operand 0 "" ""))
7412 (pc)))]
7413 ""
7414 "
7415 {
7416 if (operands[0]) /* avoid unused code warning */
7417 {
7418 gen_conditional_branch (operands, GEU);
7419 DONE;
7420 }
7421 }")
7422
7423
7424 (define_expand "bltu"
7425 [(set (pc)
7426 (if_then_else (ltu:CC (cc0)
7427 (const_int 0))
7428 (label_ref (match_operand 0 "" ""))
7429 (pc)))]
7430 ""
7431 "
7432 {
7433 if (operands[0]) /* avoid unused code warning */
7434 {
7435 gen_conditional_branch (operands, LTU);
7436 DONE;
7437 }
7438 }")
7439
7440 (define_expand "bleu"
7441 [(set (pc)
7442 (if_then_else (leu:CC (cc0)
7443 (const_int 0))
7444 (label_ref (match_operand 0 "" ""))
7445 (pc)))]
7446 ""
7447 "
7448 {
7449 if (operands[0]) /* avoid unused code warning */
7450 {
7451 gen_conditional_branch (operands, LEU);
7452 DONE;
7453 }
7454 }")
7455
7456 \f
7457 ;;
7458 ;; ....................
7459 ;;
7460 ;; SETTING A REGISTER FROM A COMPARISON
7461 ;;
7462 ;; ....................
7463
7464 (define_expand "seq"
7465 [(set (match_operand:SI 0 "register_operand" "=d")
7466 (eq:SI (match_dup 1)
7467 (match_dup 2)))]
7468 ""
7469 "
7470 {
7471 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7472 FAIL;
7473
7474 /* set up operands from compare. */
7475 operands[1] = branch_cmp[0];
7476 operands[2] = branch_cmp[1];
7477
7478 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7479 {
7480 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
7481 DONE;
7482 }
7483
7484 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7485 operands[2] = force_reg (SImode, operands[2]);
7486
7487 /* fall through and generate default code */
7488 }")
7489
7490
7491 (define_insn "seq_si_zero"
7492 [(set (match_operand:SI 0 "register_operand" "=d")
7493 (eq:SI (match_operand:SI 1 "register_operand" "d")
7494 (const_int 0)))]
7495 "!TARGET_MIPS16"
7496 "sltu\\t%0,%1,1"
7497 [(set_attr "type" "arith")
7498 (set_attr "mode" "SI")
7499 (set_attr "length" "1")])
7500
7501 (define_insn ""
7502 [(set (match_operand:SI 0 "register_operand" "=t")
7503 (eq:SI (match_operand:SI 1 "register_operand" "d")
7504 (const_int 0)))]
7505 "TARGET_MIPS16"
7506 "sltu\\t%1,1"
7507 [(set_attr "type" "arith")
7508 (set_attr "mode" "SI")
7509 (set_attr "length" "1")])
7510
7511 (define_insn "seq_di_zero"
7512 [(set (match_operand:DI 0 "register_operand" "=d")
7513 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
7514 (const_int 0)))]
7515 "TARGET_64BIT && !TARGET_MIPS16"
7516 "sltu\\t%0,%1,1"
7517 [(set_attr "type" "arith")
7518 (set_attr "mode" "DI")
7519 (set_attr "length" "1")])
7520
7521 (define_insn ""
7522 [(set (match_operand:DI 0 "register_operand" "=t")
7523 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
7524 (const_int 0)))]
7525 "TARGET_64BIT && TARGET_MIPS16"
7526 "sltu\\t%1,1"
7527 [(set_attr "type" "arith")
7528 (set_attr "mode" "DI")
7529 (set_attr "length" "1")])
7530
7531 (define_insn "seq_si"
7532 [(set (match_operand:SI 0 "register_operand" "=d,d")
7533 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
7534 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
7535 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7536 "@
7537 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
7538 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
7539 [(set_attr "type" "arith")
7540 (set_attr "mode" "SI")
7541 (set_attr "length" "2")])
7542
7543 (define_split
7544 [(set (match_operand:SI 0 "register_operand" "")
7545 (eq:SI (match_operand:SI 1 "register_operand" "")
7546 (match_operand:SI 2 "uns_arith_operand" "")))]
7547 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7548 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7549 [(set (match_dup 0)
7550 (xor:SI (match_dup 1)
7551 (match_dup 2)))
7552 (set (match_dup 0)
7553 (ltu:SI (match_dup 0)
7554 (const_int 1)))]
7555 "")
7556
7557 (define_insn "seq_di"
7558 [(set (match_operand:DI 0 "register_operand" "=d,d")
7559 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
7560 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
7561 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7562 "@
7563 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
7564 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
7565 [(set_attr "type" "arith")
7566 (set_attr "mode" "DI")
7567 (set_attr "length" "2")])
7568
7569 (define_split
7570 [(set (match_operand:DI 0 "register_operand" "")
7571 (eq:DI (match_operand:DI 1 "se_register_operand" "")
7572 (match_operand:DI 2 "se_uns_arith_operand" "")))]
7573 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7574 && !TARGET_MIPS16
7575 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7576 [(set (match_dup 0)
7577 (xor:DI (match_dup 1)
7578 (match_dup 2)))
7579 (set (match_dup 0)
7580 (ltu:DI (match_dup 0)
7581 (const_int 1)))]
7582 "")
7583
7584 ;; On the mips16 the default code is better than using sltu.
7585
7586 (define_expand "sne"
7587 [(set (match_operand:SI 0 "register_operand" "=d")
7588 (ne:SI (match_dup 1)
7589 (match_dup 2)))]
7590 "!TARGET_MIPS16"
7591 "
7592 {
7593 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7594 FAIL;
7595
7596 /* set up operands from compare. */
7597 operands[1] = branch_cmp[0];
7598 operands[2] = branch_cmp[1];
7599
7600 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
7601 {
7602 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
7603 DONE;
7604 }
7605
7606 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7607 operands[2] = force_reg (SImode, operands[2]);
7608
7609 /* fall through and generate default code */
7610 }")
7611
7612 (define_insn "sne_si_zero"
7613 [(set (match_operand:SI 0 "register_operand" "=d")
7614 (ne:SI (match_operand:SI 1 "register_operand" "d")
7615 (const_int 0)))]
7616 "!TARGET_MIPS16"
7617 "sltu\\t%0,%.,%1"
7618 [(set_attr "type" "arith")
7619 (set_attr "mode" "SI")
7620 (set_attr "length" "1")])
7621
7622 (define_insn "sne_di_zero"
7623 [(set (match_operand:DI 0 "register_operand" "=d")
7624 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
7625 (const_int 0)))]
7626 "TARGET_64BIT && !TARGET_MIPS16"
7627 "sltu\\t%0,%.,%1"
7628 [(set_attr "type" "arith")
7629 (set_attr "mode" "DI")
7630 (set_attr "length" "1")])
7631
7632 (define_insn "sne_si"
7633 [(set (match_operand:SI 0 "register_operand" "=d,d")
7634 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
7635 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
7636 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7637 "@
7638 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
7639 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
7640 [(set_attr "type" "arith")
7641 (set_attr "mode" "SI")
7642 (set_attr "length" "2")])
7643
7644 (define_split
7645 [(set (match_operand:SI 0 "register_operand" "")
7646 (ne:SI (match_operand:SI 1 "register_operand" "")
7647 (match_operand:SI 2 "uns_arith_operand" "")))]
7648 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7649 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7650 [(set (match_dup 0)
7651 (xor:SI (match_dup 1)
7652 (match_dup 2)))
7653 (set (match_dup 0)
7654 (gtu:SI (match_dup 0)
7655 (const_int 0)))]
7656 "")
7657
7658 (define_insn "sne_di"
7659 [(set (match_operand:DI 0 "register_operand" "=d,d")
7660 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
7661 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
7662 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7663 "@
7664 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
7665 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
7666 [(set_attr "type" "arith")
7667 (set_attr "mode" "DI")
7668 (set_attr "length" "2")])
7669
7670 (define_split
7671 [(set (match_operand:DI 0 "register_operand" "")
7672 (ne:DI (match_operand:DI 1 "se_register_operand" "")
7673 (match_operand:DI 2 "se_uns_arith_operand" "")))]
7674 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7675 && !TARGET_MIPS16
7676 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7677 [(set (match_dup 0)
7678 (xor:DI (match_dup 1)
7679 (match_dup 2)))
7680 (set (match_dup 0)
7681 (gtu:DI (match_dup 0)
7682 (const_int 0)))]
7683 "")
7684
7685 (define_expand "sgt"
7686 [(set (match_operand:SI 0 "register_operand" "=d")
7687 (gt:SI (match_dup 1)
7688 (match_dup 2)))]
7689 ""
7690 "
7691 {
7692 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7693 FAIL;
7694
7695 /* set up operands from compare. */
7696 operands[1] = branch_cmp[0];
7697 operands[2] = branch_cmp[1];
7698
7699 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7700 {
7701 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
7702 DONE;
7703 }
7704
7705 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
7706 operands[2] = force_reg (SImode, operands[2]);
7707
7708 /* fall through and generate default code */
7709 }")
7710
7711 (define_insn "sgt_si"
7712 [(set (match_operand:SI 0 "register_operand" "=d")
7713 (gt:SI (match_operand:SI 1 "register_operand" "d")
7714 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
7715 "!TARGET_MIPS16"
7716 "slt\\t%0,%z2,%1"
7717 [(set_attr "type" "arith")
7718 (set_attr "mode" "SI")
7719 (set_attr "length" "1")])
7720
7721 (define_insn ""
7722 [(set (match_operand:SI 0 "register_operand" "=t")
7723 (gt:SI (match_operand:SI 1 "register_operand" "d")
7724 (match_operand:SI 2 "register_operand" "d")))]
7725 "TARGET_MIPS16"
7726 "slt\\t%2,%1"
7727 [(set_attr "type" "arith")
7728 (set_attr "mode" "SI")
7729 (set_attr "length" "1")])
7730
7731 (define_insn "sgt_di"
7732 [(set (match_operand:DI 0 "register_operand" "=d")
7733 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
7734 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
7735 "TARGET_64BIT && !TARGET_MIPS16"
7736 "slt\\t%0,%z2,%1"
7737 [(set_attr "type" "arith")
7738 (set_attr "mode" "DI")
7739 (set_attr "length" "1")])
7740
7741 (define_insn ""
7742 [(set (match_operand:DI 0 "register_operand" "=d")
7743 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
7744 (match_operand:DI 2 "se_register_operand" "d")))]
7745 "TARGET_64BIT && TARGET_MIPS16"
7746 "slt\\t%2,%1"
7747 [(set_attr "type" "arith")
7748 (set_attr "mode" "DI")
7749 (set_attr "length" "1")])
7750
7751 (define_expand "sge"
7752 [(set (match_operand:SI 0 "register_operand" "=d")
7753 (ge:SI (match_dup 1)
7754 (match_dup 2)))]
7755 ""
7756 "
7757 {
7758 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7759 FAIL;
7760
7761 /* set up operands from compare. */
7762 operands[1] = branch_cmp[0];
7763 operands[2] = branch_cmp[1];
7764
7765 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7766 {
7767 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
7768 DONE;
7769 }
7770
7771 /* fall through and generate default code */
7772 }")
7773
7774 (define_insn "sge_si"
7775 [(set (match_operand:SI 0 "register_operand" "=d")
7776 (ge:SI (match_operand:SI 1 "register_operand" "d")
7777 (match_operand:SI 2 "arith_operand" "dI")))]
7778 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7779 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
7780 [(set_attr "type" "arith")
7781 (set_attr "mode" "SI")
7782 (set_attr "length" "2")])
7783
7784 (define_split
7785 [(set (match_operand:SI 0 "register_operand" "")
7786 (ge:SI (match_operand:SI 1 "register_operand" "")
7787 (match_operand:SI 2 "arith_operand" "")))]
7788 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7789 [(set (match_dup 0)
7790 (lt:SI (match_dup 1)
7791 (match_dup 2)))
7792 (set (match_dup 0)
7793 (xor:SI (match_dup 0)
7794 (const_int 1)))]
7795 "")
7796
7797 (define_insn "sge_di"
7798 [(set (match_operand:DI 0 "register_operand" "=d")
7799 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
7800 (match_operand:DI 2 "se_arith_operand" "dI")))]
7801 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7802 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
7803 [(set_attr "type" "arith")
7804 (set_attr "mode" "DI")
7805 (set_attr "length" "2")])
7806
7807 (define_split
7808 [(set (match_operand:DI 0 "register_operand" "")
7809 (ge:DI (match_operand:DI 1 "se_register_operand" "")
7810 (match_operand:DI 2 "se_arith_operand" "")))]
7811 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7812 && !TARGET_MIPS16"
7813 [(set (match_dup 0)
7814 (lt:DI (match_dup 1)
7815 (match_dup 2)))
7816 (set (match_dup 0)
7817 (xor:DI (match_dup 0)
7818 (const_int 1)))]
7819 "")
7820
7821 (define_expand "slt"
7822 [(set (match_operand:SI 0 "register_operand" "=d")
7823 (lt:SI (match_dup 1)
7824 (match_dup 2)))]
7825 ""
7826 "
7827 {
7828 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7829 FAIL;
7830
7831 /* set up operands from compare. */
7832 operands[1] = branch_cmp[0];
7833 operands[2] = branch_cmp[1];
7834
7835 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7836 {
7837 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
7838 DONE;
7839 }
7840
7841 /* fall through and generate default code */
7842 }")
7843
7844 (define_insn "slt_si"
7845 [(set (match_operand:SI 0 "register_operand" "=d")
7846 (lt:SI (match_operand:SI 1 "register_operand" "d")
7847 (match_operand:SI 2 "arith_operand" "dI")))]
7848 "!TARGET_MIPS16"
7849 "slt\\t%0,%1,%2"
7850 [(set_attr "type" "arith")
7851 (set_attr "mode" "SI")
7852 (set_attr "length" "1")])
7853
7854 (define_insn ""
7855 [(set (match_operand:SI 0 "register_operand" "=t,t")
7856 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
7857 (match_operand:SI 2 "arith_operand" "d,I")))]
7858 "TARGET_MIPS16"
7859 "slt\\t%1,%2"
7860 [(set_attr "type" "arith")
7861 (set_attr "mode" "SI")
7862 (set_attr_alternative "length"
7863 [(const_int 1)
7864 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7865 (const_int 1)
7866 (const_int 2))])])
7867
7868 (define_insn "slt_di"
7869 [(set (match_operand:DI 0 "register_operand" "=d")
7870 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
7871 (match_operand:DI 2 "se_arith_operand" "dI")))]
7872 "TARGET_64BIT && !TARGET_MIPS16"
7873 "slt\\t%0,%1,%2"
7874 [(set_attr "type" "arith")
7875 (set_attr "mode" "DI")
7876 (set_attr "length" "1")])
7877
7878 (define_insn ""
7879 [(set (match_operand:DI 0 "register_operand" "=t,t")
7880 (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
7881 (match_operand:DI 2 "se_arith_operand" "d,I")))]
7882 "TARGET_64BIT && TARGET_MIPS16"
7883 "slt\\t%1,%2"
7884 [(set_attr "type" "arith")
7885 (set_attr "mode" "DI")
7886 (set_attr_alternative "length"
7887 [(const_int 1)
7888 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7889 (const_int 1)
7890 (const_int 2))])])
7891
7892 (define_expand "sle"
7893 [(set (match_operand:SI 0 "register_operand" "=d")
7894 (le:SI (match_dup 1)
7895 (match_dup 2)))]
7896 ""
7897 "
7898 {
7899 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7900 FAIL;
7901
7902 /* set up operands from compare. */
7903 operands[1] = branch_cmp[0];
7904 operands[2] = branch_cmp[1];
7905
7906 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7907 {
7908 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
7909 DONE;
7910 }
7911
7912 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7913 operands[2] = force_reg (SImode, operands[2]);
7914
7915 /* fall through and generate default code */
7916 }")
7917
7918 (define_insn "sle_si_const"
7919 [(set (match_operand:SI 0 "register_operand" "=d")
7920 (le:SI (match_operand:SI 1 "register_operand" "d")
7921 (match_operand:SI 2 "small_int" "I")))]
7922 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7923 "*
7924 {
7925 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7926 return \"slt\\t%0,%1,%2\";
7927 }"
7928 [(set_attr "type" "arith")
7929 (set_attr "mode" "SI")
7930 (set_attr "length" "1")])
7931
7932 (define_insn ""
7933 [(set (match_operand:SI 0 "register_operand" "=t")
7934 (le:SI (match_operand:SI 1 "register_operand" "d")
7935 (match_operand:SI 2 "small_int" "I")))]
7936 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7937 "*
7938 {
7939 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7940 return \"slt\\t%1,%2\";
7941 }"
7942 [(set_attr "type" "arith")
7943 (set_attr "mode" "SI")
7944 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7945 (const_int 1)
7946 (const_int 2)))])
7947
7948 (define_insn "sle_di_const"
7949 [(set (match_operand:DI 0 "register_operand" "=d")
7950 (le:DI (match_operand:DI 1 "se_register_operand" "d")
7951 (match_operand:DI 2 "small_int" "I")))]
7952 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7953 "*
7954 {
7955 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7956 return \"slt\\t%0,%1,%2\";
7957 }"
7958 [(set_attr "type" "arith")
7959 (set_attr "mode" "DI")
7960 (set_attr "length" "1")])
7961
7962 (define_insn ""
7963 [(set (match_operand:DI 0 "register_operand" "=t")
7964 (le:DI (match_operand:DI 1 "se_register_operand" "d")
7965 (match_operand:DI 2 "small_int" "I")))]
7966 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7967 "*
7968 {
7969 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7970 return \"slt\\t%1,%2\";
7971 }"
7972 [(set_attr "type" "arith")
7973 (set_attr "mode" "DI")
7974 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7975 (const_int 1)
7976 (const_int 2)))])
7977
7978 (define_insn "sle_si_reg"
7979 [(set (match_operand:SI 0 "register_operand" "=d")
7980 (le:SI (match_operand:SI 1 "register_operand" "d")
7981 (match_operand:SI 2 "register_operand" "d")))]
7982 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7983 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
7984 [(set_attr "type" "arith")
7985 (set_attr "mode" "SI")
7986 (set_attr "length" "2")])
7987
7988 (define_split
7989 [(set (match_operand:SI 0 "register_operand" "")
7990 (le:SI (match_operand:SI 1 "register_operand" "")
7991 (match_operand:SI 2 "register_operand" "")))]
7992 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7993 [(set (match_dup 0)
7994 (lt:SI (match_dup 2)
7995 (match_dup 1)))
7996 (set (match_dup 0)
7997 (xor:SI (match_dup 0)
7998 (const_int 1)))]
7999 "")
8000
8001 (define_insn "sle_di_reg"
8002 [(set (match_operand:DI 0 "register_operand" "=d")
8003 (le:DI (match_operand:DI 1 "se_register_operand" "d")
8004 (match_operand:DI 2 "se_register_operand" "d")))]
8005 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8006 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8007 [(set_attr "type" "arith")
8008 (set_attr "mode" "DI")
8009 (set_attr "length" "2")])
8010
8011 (define_split
8012 [(set (match_operand:DI 0 "register_operand" "")
8013 (le:DI (match_operand:DI 1 "se_register_operand" "")
8014 (match_operand:DI 2 "se_register_operand" "")))]
8015 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8016 && !TARGET_MIPS16"
8017 [(set (match_dup 0)
8018 (lt:DI (match_dup 2)
8019 (match_dup 1)))
8020 (set (match_dup 0)
8021 (xor:DI (match_dup 0)
8022 (const_int 1)))]
8023 "")
8024
8025 (define_expand "sgtu"
8026 [(set (match_operand:SI 0 "register_operand" "=d")
8027 (gtu:SI (match_dup 1)
8028 (match_dup 2)))]
8029 ""
8030 "
8031 {
8032 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8033 FAIL;
8034
8035 /* set up operands from compare. */
8036 operands[1] = branch_cmp[0];
8037 operands[2] = branch_cmp[1];
8038
8039 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8040 {
8041 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8042 DONE;
8043 }
8044
8045 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8046 operands[2] = force_reg (SImode, operands[2]);
8047
8048 /* fall through and generate default code */
8049 }")
8050
8051 (define_insn "sgtu_si"
8052 [(set (match_operand:SI 0 "register_operand" "=d")
8053 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8054 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8055 ""
8056 "sltu\\t%0,%z2,%1"
8057 [(set_attr "type" "arith")
8058 (set_attr "mode" "SI")
8059 (set_attr "length" "1")])
8060
8061 (define_insn ""
8062 [(set (match_operand:SI 0 "register_operand" "=t")
8063 (gtu:SI (match_operand:SI 1 "register_operand" "d")
8064 (match_operand:SI 2 "register_operand" "d")))]
8065 ""
8066 "sltu\\t%2,%1"
8067 [(set_attr "type" "arith")
8068 (set_attr "mode" "SI")
8069 (set_attr "length" "1")])
8070
8071 (define_insn "sgtu_di"
8072 [(set (match_operand:DI 0 "register_operand" "=d")
8073 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8074 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8075 "TARGET_64BIT"
8076 "sltu\\t%0,%z2,%1"
8077 [(set_attr "type" "arith")
8078 (set_attr "mode" "DI")
8079 (set_attr "length" "1")])
8080
8081 (define_insn ""
8082 [(set (match_operand:DI 0 "register_operand" "=t")
8083 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8084 (match_operand:DI 2 "se_register_operand" "d")))]
8085 "TARGET_64BIT"
8086 "sltu\\t%2,%1"
8087 [(set_attr "type" "arith")
8088 (set_attr "mode" "DI")
8089 (set_attr "length" "1")])
8090
8091 (define_expand "sgeu"
8092 [(set (match_operand:SI 0 "register_operand" "=d")
8093 (geu:SI (match_dup 1)
8094 (match_dup 2)))]
8095 ""
8096 "
8097 {
8098 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8099 FAIL;
8100
8101 /* set up operands from compare. */
8102 operands[1] = branch_cmp[0];
8103 operands[2] = branch_cmp[1];
8104
8105 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8106 {
8107 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8108 DONE;
8109 }
8110
8111 /* fall through and generate default code */
8112 }")
8113
8114 (define_insn "sgeu_si"
8115 [(set (match_operand:SI 0 "register_operand" "=d")
8116 (geu:SI (match_operand:SI 1 "register_operand" "d")
8117 (match_operand:SI 2 "arith_operand" "dI")))]
8118 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8119 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8120 [(set_attr "type" "arith")
8121 (set_attr "mode" "SI")
8122 (set_attr "length" "2")])
8123
8124 (define_split
8125 [(set (match_operand:SI 0 "register_operand" "")
8126 (geu:SI (match_operand:SI 1 "register_operand" "")
8127 (match_operand:SI 2 "arith_operand" "")))]
8128 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8129 [(set (match_dup 0)
8130 (ltu:SI (match_dup 1)
8131 (match_dup 2)))
8132 (set (match_dup 0)
8133 (xor:SI (match_dup 0)
8134 (const_int 1)))]
8135 "")
8136
8137 (define_insn "sgeu_di"
8138 [(set (match_operand:DI 0 "register_operand" "=d")
8139 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8140 (match_operand:DI 2 "se_arith_operand" "dI")))]
8141 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8142 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8143 [(set_attr "type" "arith")
8144 (set_attr "mode" "DI")
8145 (set_attr "length" "2")])
8146
8147 (define_split
8148 [(set (match_operand:DI 0 "register_operand" "")
8149 (geu:DI (match_operand:DI 1 "se_register_operand" "")
8150 (match_operand:DI 2 "se_arith_operand" "")))]
8151 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8152 && !TARGET_MIPS16"
8153 [(set (match_dup 0)
8154 (ltu:DI (match_dup 1)
8155 (match_dup 2)))
8156 (set (match_dup 0)
8157 (xor:DI (match_dup 0)
8158 (const_int 1)))]
8159 "")
8160
8161 (define_expand "sltu"
8162 [(set (match_operand:SI 0 "register_operand" "=d")
8163 (ltu:SI (match_dup 1)
8164 (match_dup 2)))]
8165 ""
8166 "
8167 {
8168 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8169 FAIL;
8170
8171 /* set up operands from compare. */
8172 operands[1] = branch_cmp[0];
8173 operands[2] = branch_cmp[1];
8174
8175 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8176 {
8177 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8178 DONE;
8179 }
8180
8181 /* fall through and generate default code */
8182 }")
8183
8184 (define_insn "sltu_si"
8185 [(set (match_operand:SI 0 "register_operand" "=d")
8186 (ltu:SI (match_operand:SI 1 "register_operand" "d")
8187 (match_operand:SI 2 "arith_operand" "dI")))]
8188 "!TARGET_MIPS16"
8189 "sltu\\t%0,%1,%2"
8190 [(set_attr "type" "arith")
8191 (set_attr "mode" "SI")
8192 (set_attr "length" "1")])
8193
8194 (define_insn ""
8195 [(set (match_operand:SI 0 "register_operand" "=t,t")
8196 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8197 (match_operand:SI 2 "arith_operand" "d,I")))]
8198 "TARGET_MIPS16"
8199 "sltu\\t%1,%2"
8200 [(set_attr "type" "arith")
8201 (set_attr "mode" "SI")
8202 (set_attr_alternative "length"
8203 [(const_int 1)
8204 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8205 (const_int 1)
8206 (const_int 2))])])
8207
8208 (define_insn "sltu_di"
8209 [(set (match_operand:DI 0 "register_operand" "=d")
8210 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8211 (match_operand:DI 2 "se_arith_operand" "dI")))]
8212 "TARGET_64BIT && !TARGET_MIPS16"
8213 "sltu\\t%0,%1,%2"
8214 [(set_attr "type" "arith")
8215 (set_attr "mode" "DI")
8216 (set_attr "length" "1")])
8217
8218 (define_insn ""
8219 [(set (match_operand:DI 0 "register_operand" "=t,t")
8220 (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8221 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8222 "TARGET_64BIT && TARGET_MIPS16"
8223 "sltu\\t%1,%2"
8224 [(set_attr "type" "arith")
8225 (set_attr "mode" "DI")
8226 (set_attr_alternative "length"
8227 [(const_int 1)
8228 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8229 (const_int 1)
8230 (const_int 2))])])
8231
8232 (define_expand "sleu"
8233 [(set (match_operand:SI 0 "register_operand" "=d")
8234 (leu:SI (match_dup 1)
8235 (match_dup 2)))]
8236 ""
8237 "
8238 {
8239 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8240 FAIL;
8241
8242 /* set up operands from compare. */
8243 operands[1] = branch_cmp[0];
8244 operands[2] = branch_cmp[1];
8245
8246 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8247 {
8248 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8249 DONE;
8250 }
8251
8252 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8253 operands[2] = force_reg (SImode, operands[2]);
8254
8255 /* fall through and generate default code */
8256 }")
8257
8258 (define_insn "sleu_si_const"
8259 [(set (match_operand:SI 0 "register_operand" "=d")
8260 (leu:SI (match_operand:SI 1 "register_operand" "d")
8261 (match_operand:SI 2 "small_int" "I")))]
8262 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8263 "*
8264 {
8265 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8266 return \"sltu\\t%0,%1,%2\";
8267 }"
8268 [(set_attr "type" "arith")
8269 (set_attr "mode" "SI")
8270 (set_attr "length" "1")])
8271
8272 (define_insn ""
8273 [(set (match_operand:SI 0 "register_operand" "=t")
8274 (leu:SI (match_operand:SI 1 "register_operand" "d")
8275 (match_operand:SI 2 "small_int" "I")))]
8276 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8277 "*
8278 {
8279 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8280 return \"sltu\\t%1,%2\";
8281 }"
8282 [(set_attr "type" "arith")
8283 (set_attr "mode" "SI")
8284 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8285 (const_int 1)
8286 (const_int 2)))])
8287
8288 (define_insn "sleu_di_const"
8289 [(set (match_operand:DI 0 "register_operand" "=d")
8290 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8291 (match_operand:DI 2 "small_int" "I")))]
8292 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8293 "*
8294 {
8295 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8296 return \"sltu\\t%0,%1,%2\";
8297 }"
8298 [(set_attr "type" "arith")
8299 (set_attr "mode" "DI")
8300 (set_attr "length" "1")])
8301
8302 (define_insn ""
8303 [(set (match_operand:DI 0 "register_operand" "=t")
8304 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8305 (match_operand:DI 2 "small_int" "I")))]
8306 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8307 "*
8308 {
8309 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8310 return \"sltu\\t%1,%2\";
8311 }"
8312 [(set_attr "type" "arith")
8313 (set_attr "mode" "DI")
8314 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8315 (const_int 1)
8316 (const_int 2)))])
8317
8318 (define_insn "sleu_si_reg"
8319 [(set (match_operand:SI 0 "register_operand" "=d")
8320 (leu:SI (match_operand:SI 1 "register_operand" "d")
8321 (match_operand:SI 2 "register_operand" "d")))]
8322 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8323 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8324 [(set_attr "type" "arith")
8325 (set_attr "mode" "SI")
8326 (set_attr "length" "2")])
8327
8328 (define_split
8329 [(set (match_operand:SI 0 "register_operand" "")
8330 (leu:SI (match_operand:SI 1 "register_operand" "")
8331 (match_operand:SI 2 "register_operand" "")))]
8332 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8333 [(set (match_dup 0)
8334 (ltu:SI (match_dup 2)
8335 (match_dup 1)))
8336 (set (match_dup 0)
8337 (xor:SI (match_dup 0)
8338 (const_int 1)))]
8339 "")
8340
8341 (define_insn "sleu_di_reg"
8342 [(set (match_operand:DI 0 "register_operand" "=d")
8343 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8344 (match_operand:DI 2 "se_register_operand" "d")))]
8345 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8346 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8347 [(set_attr "type" "arith")
8348 (set_attr "mode" "DI")
8349 (set_attr "length" "2")])
8350
8351 (define_split
8352 [(set (match_operand:DI 0 "register_operand" "")
8353 (leu:DI (match_operand:DI 1 "se_register_operand" "")
8354 (match_operand:DI 2 "se_register_operand" "")))]
8355 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8356 && !TARGET_MIPS16"
8357 [(set (match_dup 0)
8358 (ltu:DI (match_dup 2)
8359 (match_dup 1)))
8360 (set (match_dup 0)
8361 (xor:DI (match_dup 0)
8362 (const_int 1)))]
8363 "")
8364
8365 \f
8366 ;;
8367 ;; ....................
8368 ;;
8369 ;; FLOATING POINT COMPARISONS
8370 ;;
8371 ;; ....................
8372
8373 (define_insn "seq_df"
8374 [(set (match_operand:CC 0 "register_operand" "=z")
8375 (eq:CC (match_operand:DF 1 "register_operand" "f")
8376 (match_operand:DF 2 "register_operand" "f")))]
8377 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8378 "*
8379 {
8380 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8381 }"
8382 [(set_attr "type" "fcmp")
8383 (set_attr "mode" "FPSW")
8384 (set_attr "length" "1")])
8385
8386 (define_insn "slt_df"
8387 [(set (match_operand:CC 0 "register_operand" "=z")
8388 (lt:CC (match_operand:DF 1 "register_operand" "f")
8389 (match_operand:DF 2 "register_operand" "f")))]
8390 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8391 "*
8392 {
8393 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8394 }"
8395 [(set_attr "type" "fcmp")
8396 (set_attr "mode" "FPSW")
8397 (set_attr "length" "1")])
8398
8399 (define_insn "sle_df"
8400 [(set (match_operand:CC 0 "register_operand" "=z")
8401 (le:CC (match_operand:DF 1 "register_operand" "f")
8402 (match_operand:DF 2 "register_operand" "f")))]
8403 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8404 "*
8405 {
8406 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8407 }"
8408 [(set_attr "type" "fcmp")
8409 (set_attr "mode" "FPSW")
8410 (set_attr "length" "1")])
8411
8412 (define_insn "sgt_df"
8413 [(set (match_operand:CC 0 "register_operand" "=z")
8414 (gt:CC (match_operand:DF 1 "register_operand" "f")
8415 (match_operand:DF 2 "register_operand" "f")))]
8416 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8417 "*
8418 {
8419 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8420 }"
8421 [(set_attr "type" "fcmp")
8422 (set_attr "mode" "FPSW")
8423 (set_attr "length" "1")])
8424
8425 (define_insn "sge_df"
8426 [(set (match_operand:CC 0 "register_operand" "=z")
8427 (ge:CC (match_operand:DF 1 "register_operand" "f")
8428 (match_operand:DF 2 "register_operand" "f")))]
8429 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8430 "*
8431 {
8432 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8433 }"
8434 [(set_attr "type" "fcmp")
8435 (set_attr "mode" "FPSW")
8436 (set_attr "length" "1")])
8437
8438 (define_insn "seq_sf"
8439 [(set (match_operand:CC 0 "register_operand" "=z")
8440 (eq:CC (match_operand:SF 1 "register_operand" "f")
8441 (match_operand:SF 2 "register_operand" "f")))]
8442 "TARGET_HARD_FLOAT"
8443 "*
8444 {
8445 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8446 }"
8447 [(set_attr "type" "fcmp")
8448 (set_attr "mode" "FPSW")
8449 (set_attr "length" "1")])
8450
8451 (define_insn "slt_sf"
8452 [(set (match_operand:CC 0 "register_operand" "=z")
8453 (lt:CC (match_operand:SF 1 "register_operand" "f")
8454 (match_operand:SF 2 "register_operand" "f")))]
8455 "TARGET_HARD_FLOAT"
8456 "*
8457 {
8458 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8459 }"
8460 [(set_attr "type" "fcmp")
8461 (set_attr "mode" "FPSW")
8462 (set_attr "length" "1")])
8463
8464 (define_insn "sle_sf"
8465 [(set (match_operand:CC 0 "register_operand" "=z")
8466 (le:CC (match_operand:SF 1 "register_operand" "f")
8467 (match_operand:SF 2 "register_operand" "f")))]
8468 "TARGET_HARD_FLOAT"
8469 "*
8470 {
8471 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8472 }"
8473 [(set_attr "type" "fcmp")
8474 (set_attr "mode" "FPSW")
8475 (set_attr "length" "1")])
8476
8477 (define_insn "sgt_sf"
8478 [(set (match_operand:CC 0 "register_operand" "=z")
8479 (gt:CC (match_operand:SF 1 "register_operand" "f")
8480 (match_operand:SF 2 "register_operand" "f")))]
8481 "TARGET_HARD_FLOAT"
8482 "*
8483 {
8484 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8485 }"
8486 [(set_attr "type" "fcmp")
8487 (set_attr "mode" "FPSW")
8488 (set_attr "length" "1")])
8489
8490 (define_insn "sge_sf"
8491 [(set (match_operand:CC 0 "register_operand" "=z")
8492 (ge:CC (match_operand:SF 1 "register_operand" "f")
8493 (match_operand:SF 2 "register_operand" "f")))]
8494 "TARGET_HARD_FLOAT"
8495 "*
8496 {
8497 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8498 }"
8499 [(set_attr "type" "fcmp")
8500 (set_attr "mode" "FPSW")
8501 (set_attr "length" "1")])
8502
8503 \f
8504 ;;
8505 ;; ....................
8506 ;;
8507 ;; UNCONDITIONAL BRANCHES
8508 ;;
8509 ;; ....................
8510
8511 ;; Unconditional branches.
8512
8513 (define_insn "jump"
8514 [(set (pc)
8515 (label_ref (match_operand 0 "" "")))]
8516 "!TARGET_MIPS16"
8517 "*
8518 {
8519 if (GET_CODE (operands[0]) == REG)
8520 return \"%*j\\t%0\";
8521 /* ??? I don't know why this is necessary. This works around an
8522 assembler problem that appears when a label is defined, then referenced
8523 in a switch table, then used in a `j' instruction. */
8524 else if (mips_abi != ABI_32)
8525 return \"%*b\\t%l0\";
8526 else
8527 return \"%*j\\t%l0\";
8528 }"
8529 [(set_attr "type" "jump")
8530 (set_attr "mode" "none")
8531 (set_attr "length" "1")])
8532
8533 ;; We need a different insn for the mips16, because a mips16 branch
8534 ;; does not have a delay slot.
8535
8536 (define_insn ""
8537 [(set (pc)
8538 (label_ref (match_operand 0 "" "")))]
8539 "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
8540 "b\\t%l0"
8541 [(set_attr "type" "branch")
8542 (set_attr "mode" "none")
8543 (set_attr "length" "2")])
8544
8545 (define_expand "indirect_jump"
8546 [(set (pc) (match_operand 0 "register_operand" "d"))]
8547 ""
8548 "
8549 {
8550 rtx dest;
8551
8552 if (operands[0]) /* eliminate unused code warnings */
8553 {
8554 dest = operands[0];
8555 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
8556 operands[0] = copy_to_mode_reg (Pmode, dest);
8557
8558 if (!TARGET_LONG64)
8559 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
8560 else
8561 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
8562
8563 DONE;
8564 }
8565 }")
8566
8567 (define_insn "indirect_jump_internal1"
8568 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
8569 "!TARGET_LONG64"
8570 "%*j\\t%0"
8571 [(set_attr "type" "jump")
8572 (set_attr "mode" "none")
8573 (set_attr "length" "1")])
8574
8575 (define_insn "indirect_jump_internal2"
8576 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
8577 "TARGET_LONG64"
8578 "%*j\\t%0"
8579 [(set_attr "type" "jump")
8580 (set_attr "mode" "none")
8581 (set_attr "length" "1")])
8582
8583 (define_expand "tablejump"
8584 [(set (pc)
8585 (match_operand 0 "register_operand" "d"))
8586 (use (label_ref (match_operand 1 "" "")))]
8587 ""
8588 "
8589 {
8590 rtx dest;
8591
8592 if (operands[0]) /* eliminate unused code warnings */
8593 {
8594 if (TARGET_MIPS16)
8595 {
8596 if (GET_MODE (operands[0]) != HImode)
8597 abort ();
8598 if (!TARGET_LONG64)
8599 emit_jump_insn (gen_tablejump_mips161 (operands[0], operands[1]));
8600 else
8601 emit_jump_insn (gen_tablejump_mips162 (operands[0], operands[1]));
8602 DONE;
8603 }
8604
8605 if (GET_MODE (operands[0]) != Pmode)
8606 abort ();
8607
8608 if (! flag_pic)
8609 {
8610 if (!TARGET_LONG64)
8611 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
8612 else
8613 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
8614 }
8615 else
8616 {
8617 if (!TARGET_LONG64)
8618 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
8619 else
8620 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
8621 }
8622
8623 DONE;
8624 }
8625 }")
8626
8627 (define_insn "tablejump_internal1"
8628 [(set (pc)
8629 (match_operand:SI 0 "register_operand" "d"))
8630 (use (label_ref (match_operand 1 "" "")))]
8631 "!TARGET_LONG64"
8632 "%*j\\t%0"
8633 [(set_attr "type" "jump")
8634 (set_attr "mode" "none")
8635 (set_attr "length" "1")])
8636
8637 (define_insn "tablejump_internal2"
8638 [(set (pc)
8639 (match_operand:DI 0 "se_register_operand" "d"))
8640 (use (label_ref (match_operand 1 "" "")))]
8641 "TARGET_LONG64"
8642 "%*j\\t%0"
8643 [(set_attr "type" "jump")
8644 (set_attr "mode" "none")
8645 (set_attr "length" "1")])
8646
8647 (define_expand "tablejump_internal3"
8648 [(set (pc)
8649 (plus:SI (match_operand:SI 0 "register_operand" "d")
8650 (label_ref:SI (match_operand:SI 1 "" ""))))]
8651 ""
8652 "")
8653
8654 (define_expand "tablejump_mips161"
8655 [(set (pc) (plus:SI (sign_extend:SI
8656 (match_operand:HI 0 "register_operand" "d"))
8657 (label_ref:SI (match_operand:SI 1 "" ""))))]
8658 "TARGET_MIPS16 && !TARGET_LONG64"
8659 "
8660 {
8661 if (operands[0]) /* eliminate unused code warnings. */
8662 {
8663 rtx t1, t2, t3;
8664
8665 t1 = gen_reg_rtx (SImode);
8666 t2 = gen_reg_rtx (SImode);
8667 t3 = gen_reg_rtx (SImode);
8668 emit_insn (gen_extendhisi2 (t1, operands[0]));
8669 emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
8670 emit_insn (gen_addsi3 (t3, t1, t2));
8671 emit_insn (gen_tablejump_internal1 (t3, operands[1]));
8672 DONE;
8673 }
8674 }")
8675
8676 (define_expand "tablejump_mips162"
8677 [(set (pc) (plus:DI (sign_extend:DI
8678 (match_operand:HI 0 "register_operand" "d"))
8679 (label_ref:DI (match_operand:SI 1 "" ""))))]
8680 "TARGET_MIPS16 && TARGET_LONG64"
8681 "
8682 {
8683 if (operands[0]) /* eliminate unused code warnings. */
8684 {
8685 rtx t1, t2, t3;
8686
8687 t1 = gen_reg_rtx (DImode);
8688 t2 = gen_reg_rtx (DImode);
8689 t3 = gen_reg_rtx (DImode);
8690 emit_insn (gen_extendhidi2 (t1, operands[0]));
8691 emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
8692 emit_insn (gen_adddi3 (t3, t1, t2));
8693 emit_insn (gen_tablejump_internal2 (t3, operands[1]));
8694 DONE;
8695 }
8696 }")
8697
8698 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
8699 ;;; it is not valid.
8700
8701 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
8702 ;;; We just use the conservative number here.
8703
8704 (define_insn ""
8705 [(set (pc)
8706 (plus:SI (match_operand:SI 0 "register_operand" "d")
8707 (label_ref:SI (match_operand:SI 1 "" ""))))]
8708 "!TARGET_LONG64 && next_active_insn (insn) != 0
8709 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
8710 && PREV_INSN (next_active_insn (insn)) == operands[1]"
8711 "*
8712 {
8713 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
8714 if (mips_abi == ABI_32)
8715 output_asm_insn (\".cpadd\\t%0\", operands);
8716 return \"%*j\\t%0\";
8717 }"
8718 [(set_attr "type" "jump")
8719 (set_attr "mode" "none")
8720 (set_attr "length" "2")])
8721
8722 (define_expand "tablejump_internal4"
8723 [(set (pc)
8724 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
8725 (label_ref:DI (match_operand:SI 1 "" ""))))]
8726 ""
8727 "")
8728
8729 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
8730 ;;; it is not valid.
8731
8732 (define_insn ""
8733 [(set (pc)
8734 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
8735 (label_ref:DI (match_operand:SI 1 "" ""))))]
8736 "TARGET_LONG64 && next_active_insn (insn) != 0
8737 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
8738 && PREV_INSN (next_active_insn (insn)) == operands[1]"
8739 "%*j\\t%0"
8740 [(set_attr "type" "jump")
8741 (set_attr "mode" "none")
8742 (set_attr "length" "1")])
8743
8744 ;; Implement a switch statement when generating embedded PIC code.
8745 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
8746
8747 (define_expand "casesi"
8748 [(set (match_dup 5)
8749 (minus:SI (match_operand:SI 0 "register_operand" "d")
8750 (match_operand:SI 1 "arith_operand" "dI")))
8751 (set (cc0)
8752 (compare:CC (match_dup 5)
8753 (match_operand:SI 2 "arith_operand" "")))
8754 (set (pc)
8755 (if_then_else (gtu (cc0)
8756 (const_int 0))
8757 (label_ref (match_operand 4 "" ""))
8758 (pc)))
8759 (parallel
8760 [(set (pc)
8761 (mem:SI (plus:SI (mult:SI (match_dup 5)
8762 (const_int 4))
8763 (label_ref (match_operand 3 "" "")))))
8764 (clobber (match_scratch:SI 6 ""))
8765 (clobber (reg:SI 31))])]
8766 "TARGET_EMBEDDED_PIC"
8767 "
8768 {
8769 /* We need slightly different code for eight byte table entries. */
8770 if (TARGET_LONG64)
8771 abort ();
8772
8773 if (operands[0])
8774 {
8775 rtx reg = gen_reg_rtx (SImode);
8776
8777 /* If the index is too large, go to the default label. */
8778 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
8779 emit_insn (gen_cmpsi (reg, operands[2]));
8780 emit_insn (gen_bgtu (operands[4]));
8781
8782 /* Do the PIC jump. */
8783 emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
8784
8785 DONE;
8786 }
8787 }")
8788
8789 ;; An embedded PIC switch statement looks like this:
8790 ;; bal $LS1
8791 ;; sll $reg,$index,2
8792 ;; $LS1:
8793 ;; addu $reg,$reg,$31
8794 ;; lw $reg,$L1-$LS1($reg)
8795 ;; addu $reg,$reg,$31
8796 ;; j $reg
8797 ;; $L1:
8798 ;; .word case1-$LS1
8799 ;; .word case2-$LS1
8800 ;; ...
8801
8802 (define_insn "casesi_internal"
8803 [(set (pc)
8804 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
8805 (const_int 4))
8806 (label_ref (match_operand 1 "" "")))))
8807 (clobber (match_operand:SI 2 "register_operand" "d"))
8808 (clobber (reg:SI 31))]
8809 "TARGET_EMBEDDED_PIC"
8810 "*
8811 {
8812 output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
8813 output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
8814 output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
8815 return \"j\\t%0\";
8816 }"
8817 [(set_attr "type" "jump")
8818 (set_attr "mode" "none")
8819 (set_attr "length" "6")])
8820
8821 ;; ??? This is a hack to work around a problem with expand_builtin_setjmp.
8822 ;; It restores the frame pointer, and then does a call to restore the global
8823 ;; pointer (gp) register. The call insn implicitly (via the assembler) reloads
8824 ;; gp from the stack. However, call insns do not depend on $fp, so it is
8825 ;; possible for the instruction scheduler to move the fp restore after the
8826 ;; call, which then causes gp to be corrupted. We fix this by emitting a
8827 ;; scheduler barrier. A better fix is to put code here that restores the
8828 ;; $gp, and then the call is unnecessary. This is only a problem when PIC
8829 ;; (TARGET_ABICALLS), and only when the gp register is caller-saved
8830 ;; (irix5/o32, but not irix6/n32/n64).
8831
8832 (define_expand "nonlocal_goto_receiver"
8833 [(const_int 0)]
8834 ""
8835 "
8836 {
8837 emit_insn (gen_blockage ());
8838 }")
8839
8840 ;; For n32/n64, we need to restore gp after a builtin setjmp. We do this
8841 ;; by making use of the fact that we've just called __dummy.
8842
8843 (define_expand "builtin_setjmp_receiver"
8844 [(const_int 0)]
8845 "TARGET_ABICALLS && mips_abi != ABI_32"
8846 "
8847 {
8848 emit_insn (gen_loadgp (gen_rtx (SYMBOL_REF, Pmode, \"__dummy\")));
8849 emit_insn (gen_blockage ());
8850 }")
8851 \f
8852 ;;
8853 ;; ....................
8854 ;;
8855 ;; Function prologue/epilogue
8856 ;;
8857 ;; ....................
8858 ;;
8859
8860 (define_expand "prologue"
8861 [(const_int 1)]
8862 ""
8863 "
8864 {
8865 if (mips_isa >= 0) /* avoid unused code warnings */
8866 {
8867 mips_expand_prologue ();
8868 DONE;
8869 }
8870 }")
8871
8872 ;; Block any insns from being moved before this point, since the
8873 ;; profiling call to mcount can use various registers that aren't
8874 ;; saved or used to pass arguments.
8875
8876 (define_insn "blockage"
8877 [(unspec_volatile [(const_int 0)] 0)]
8878 ""
8879 ""
8880 [(set_attr "type" "unknown")
8881 (set_attr "mode" "none")
8882 (set_attr "length" "0")])
8883
8884 (define_expand "epilogue"
8885 [(const_int 2)]
8886 ""
8887 "
8888 {
8889 if (mips_isa >= 0) /* avoid unused code warnings */
8890 {
8891 mips_expand_epilogue ();
8892 DONE;
8893 }
8894 }")
8895
8896 ;; Trivial return. Make it look like a normal return insn as that
8897 ;; allows jump optimizations to work better .
8898 (define_insn "return"
8899 [(return)]
8900 "mips_can_use_return_insn ()"
8901 "%*j\\t$31"
8902 [(set_attr "type" "jump")
8903 (set_attr "mode" "none")
8904 (set_attr "length" "1")])
8905
8906 ;; Normal return.
8907 ;; We match any mode for the return address, so that this will work with
8908 ;; both 32 bit and 64 bit targets.
8909 (define_insn "return_internal"
8910 [(use (match_operand 0 "register_operand" ""))
8911 (return)]
8912 ""
8913 "*
8914 {
8915 return \"%*j\\t%0\";
8916 }"
8917 [(set_attr "type" "jump")
8918 (set_attr "mode" "none")
8919 (set_attr "length" "1")])
8920
8921 ;; When generating embedded PIC code we need to get the address of the
8922 ;; current function. This specialized instruction does just that.
8923
8924 (define_insn "get_fnaddr"
8925 [(set (match_operand 0 "register_operand" "=d")
8926 (unspec [(match_operand 1 "" "")] 1))
8927 (clobber (reg:SI 31))]
8928 "TARGET_EMBEDDED_PIC
8929 && GET_CODE (operands[1]) == SYMBOL_REF"
8930 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
8931 [(set_attr "type" "call")
8932 (set_attr "mode" "none")
8933 (set_attr "length" "4")])
8934
8935 \f
8936 ;;
8937 ;; ....................
8938 ;;
8939 ;; FUNCTION CALLS
8940 ;;
8941 ;; ....................
8942
8943 ;; calls.c now passes a third argument, make saber happy
8944
8945 (define_expand "call"
8946 [(parallel [(call (match_operand 0 "memory_operand" "m")
8947 (match_operand 1 "" "i"))
8948 (clobber (reg:SI 31))
8949 (use (match_operand 2 "" "")) ;; next_arg_reg
8950 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
8951 ""
8952 "
8953 {
8954 rtx addr;
8955
8956 if (operands[0]) /* eliminate unused code warnings */
8957 {
8958 addr = XEXP (operands[0], 0);
8959 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
8960 || ! call_insn_operand (addr, VOIDmode))
8961 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
8962
8963 /* In order to pass small structures by value in registers
8964 compatibly with the MIPS compiler, we need to shift the value
8965 into the high part of the register. Function_arg has encoded
8966 a PARALLEL rtx, holding a vector of adjustments to be made
8967 as the next_arg_reg variable, so we split up the insns,
8968 and emit them separately. */
8969
8970 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
8971 {
8972 rtvec adjust = XVEC (operands[2], 0);
8973 int num = GET_NUM_ELEM (adjust);
8974 int i;
8975
8976 for (i = 0; i < num; i++)
8977 emit_insn (RTVEC_ELT (adjust, i));
8978 }
8979
8980 if (TARGET_MIPS16
8981 && mips16_hard_float
8982 && operands[2] != 0
8983 && (int) GET_MODE (operands[2]) != 0)
8984 {
8985 if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
8986 (int) GET_MODE (operands[2])))
8987 DONE;
8988 }
8989
8990 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
8991 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
8992
8993 DONE;
8994 }
8995 }")
8996
8997 (define_expand "call_internal0"
8998 [(parallel [(call (match_operand 0 "" "")
8999 (match_operand 1 "" ""))
9000 (clobber (match_operand:SI 2 "" ""))])]
9001 ""
9002 "")
9003
9004 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9005 ;; don't have a constraint letter for it.
9006
9007 (define_insn ""
9008 [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9009 (match_operand 1 "" "i"))
9010 (clobber (match_operand:SI 2 "register_operand" "=y"))]
9011 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9012 && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9013 "%*jal\\t%0"
9014 [(set_attr "type" "call")
9015 (set_attr "mode" "none")
9016 (set_attr "length" "2")])
9017
9018 (define_insn "call_internal1"
9019 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9020 (match_operand 1 "" "i"))
9021 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9022 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9023 "*
9024 {
9025 register rtx target = operands[0];
9026
9027 if (GET_CODE (target) == SYMBOL_REF)
9028 return \"%*jal\\t%0\";
9029 else if (GET_CODE (target) == CONST_INT)
9030 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9031 else
9032 return \"%*jal\\t%2,%0\";
9033 }"
9034 [(set_attr "type" "call")
9035 (set_attr "mode" "none")
9036 (set_attr "length" "1")])
9037
9038 (define_insn "call_internal2"
9039 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9040 (match_operand 1 "" "i"))
9041 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9042 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9043 "*
9044 {
9045 register rtx target = operands[0];
9046
9047 if (GET_CODE (target) == SYMBOL_REF)
9048 {
9049 if (GET_MODE (target) == SImode)
9050 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9051 else
9052 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9053 }
9054 else if (GET_CODE (target) == CONST_INT)
9055 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9056 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9057 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9058 else
9059 return \"jal\\t%2,%0\";
9060 }"
9061 [(set_attr "type" "call")
9062 (set_attr "mode" "none")
9063 (set_attr "length" "2")])
9064
9065 (define_insn "call_internal3a"
9066 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9067 (match_operand 1 "" "i"))
9068 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9069 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9070 "%*jal\\t%2,%0"
9071 [(set_attr "type" "call")
9072 (set_attr "mode" "none")
9073 (set_attr "length" "1")])
9074
9075 (define_insn "call_internal3b"
9076 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9077 (match_operand 1 "" "i"))
9078 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9079 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9080 "%*jal\\t%2,%0"
9081 [(set_attr "type" "call")
9082 (set_attr "mode" "none")
9083 (set_attr "length" "1")])
9084
9085 (define_insn "call_internal4a"
9086 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9087 (match_operand 1 "" "i"))
9088 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9089 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9090 "*
9091 {
9092 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9093 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9094 else
9095 return \"jal\\t%2,%0\";
9096 }"
9097 [(set_attr "type" "call")
9098 (set_attr "mode" "none")
9099 (set_attr "length" "2")])
9100
9101 (define_insn "call_internal4b"
9102 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9103 (match_operand 1 "" "i"))
9104 (clobber (match_operand:SI 2 "register_operand" "=d"))]
9105 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9106 "*
9107 {
9108 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9109 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9110 else
9111 return \"jal\\t%2,%0\";
9112 }"
9113 [(set_attr "type" "call")
9114 (set_attr "mode" "none")
9115 (set_attr "length" "2")])
9116
9117 ;; calls.c now passes a fourth argument, make saber happy
9118
9119 (define_expand "call_value"
9120 [(parallel [(set (match_operand 0 "register_operand" "=df")
9121 (call (match_operand 1 "memory_operand" "m")
9122 (match_operand 2 "" "i")))
9123 (clobber (reg:SI 31))
9124 (use (match_operand 3 "" ""))])] ;; next_arg_reg
9125 ""
9126 "
9127 {
9128 rtx addr;
9129
9130 if (operands[0]) /* eliminate unused code warning */
9131 {
9132 addr = XEXP (operands[1], 0);
9133 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9134 || ! call_insn_operand (addr, VOIDmode))
9135 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9136
9137 /* In order to pass small structures by value in registers
9138 compatibly with the MIPS compiler, we need to shift the value
9139 into the high part of the register. Function_arg has encoded
9140 a PARALLEL rtx, holding a vector of adjustments to be made
9141 as the next_arg_reg variable, so we split up the insns,
9142 and emit them separately. */
9143
9144 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9145 {
9146 rtvec adjust = XVEC (operands[3], 0);
9147 int num = GET_NUM_ELEM (adjust);
9148 int i;
9149
9150 for (i = 0; i < num; i++)
9151 emit_insn (RTVEC_ELT (adjust, i));
9152 }
9153
9154 if (TARGET_MIPS16
9155 && mips16_hard_float
9156 && ((operands[3] != 0
9157 && (int) GET_MODE (operands[3]) != 0)
9158 || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9159 {
9160 if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9161 (operands[3] == 0 ? 0
9162 : (int) GET_MODE (operands[3]))))
9163 DONE;
9164 }
9165
9166 /* Handle Irix6 function calls that have multiple non-contiguous
9167 results. */
9168 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9169 {
9170 emit_call_insn (gen_call_value_multiple_internal0
9171 (XEXP (XVECEXP (operands[0], 0, 0), 0),
9172 operands[1], operands[2],
9173 XEXP (XVECEXP (operands[0], 0, 1), 0),
9174 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9175 DONE;
9176 }
9177
9178 /* We have a call returning a DImode structure in an FP reg.
9179 Strip off the now unnecessary PARALLEL. */
9180 if (GET_CODE (operands[0]) == PARALLEL)
9181 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9182
9183 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9184 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9185
9186 DONE;
9187 }
9188 }")
9189
9190 (define_expand "call_value_internal0"
9191 [(parallel [(set (match_operand 0 "" "")
9192 (call (match_operand 1 "" "")
9193 (match_operand 2 "" "")))
9194 (clobber (match_operand:SI 3 "" ""))])]
9195 ""
9196 "")
9197
9198 ;; Recognize $31 specially on the mips16, because we don't have a
9199 ;; constraint letter for it.
9200
9201 (define_insn ""
9202 [(set (match_operand 0 "register_operand" "=d")
9203 (call (mem (match_operand 1 "call_insn_operand" "ei"))
9204 (match_operand 2 "" "i")))
9205 (clobber (match_operand:SI 3 "register_operand" "=y"))]
9206 "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9207 && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9208 "%*jal\\t%1"
9209 [(set_attr "type" "call")
9210 (set_attr "mode" "none")
9211 (set_attr "length" "2")])
9212
9213 (define_insn "call_value_internal1"
9214 [(set (match_operand 0 "register_operand" "=df")
9215 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9216 (match_operand 2 "" "i")))
9217 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9218 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9219 "*
9220 {
9221 register rtx target = operands[1];
9222
9223 if (GET_CODE (target) == SYMBOL_REF)
9224 return \"%*jal\\t%1\";
9225 else if (GET_CODE (target) == CONST_INT)
9226 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
9227 else
9228 return \"%*jal\\t%3,%1\";
9229 }"
9230 [(set_attr "type" "call")
9231 (set_attr "mode" "none")
9232 (set_attr "length" "1")])
9233
9234 (define_insn "call_value_internal2"
9235 [(set (match_operand 0 "register_operand" "=df")
9236 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9237 (match_operand 2 "" "i")))
9238 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9239 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9240 "*
9241 {
9242 register rtx target = operands[1];
9243
9244 if (GET_CODE (target) == SYMBOL_REF)
9245 {
9246 if (GET_MODE (target) == SImode)
9247 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
9248 else
9249 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
9250 }
9251 else if (GET_CODE (target) == CONST_INT)
9252 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
9253 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9254 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9255 else
9256 return \"jal\\t%3,%1\";
9257 }"
9258 [(set_attr "type" "call")
9259 (set_attr "mode" "none")
9260 (set_attr "length" "2")])
9261
9262 (define_insn "call_value_internal3a"
9263 [(set (match_operand 0 "register_operand" "=df")
9264 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9265 (match_operand 2 "" "i")))
9266 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9267 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9268 "%*jal\\t%3,%1"
9269 [(set_attr "type" "call")
9270 (set_attr "mode" "none")
9271 (set_attr "length" "1")])
9272
9273 (define_insn "call_value_internal3b"
9274 [(set (match_operand 0 "register_operand" "=df")
9275 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9276 (match_operand 2 "" "i")))
9277 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9278 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9279 "%*jal\\t%3,%1"
9280 [(set_attr "type" "call")
9281 (set_attr "mode" "none")
9282 (set_attr "length" "1")])
9283
9284 (define_insn "call_value_internal4a"
9285 [(set (match_operand 0 "register_operand" "=df")
9286 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9287 (match_operand 2 "" "i")))
9288 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9289 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9290 "*
9291 {
9292 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9293 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9294 else
9295 return \"jal\\t%3,%1\";
9296 }"
9297 [(set_attr "type" "call")
9298 (set_attr "mode" "none")
9299 (set_attr "length" "2")])
9300
9301 (define_insn "call_value_internal4b"
9302 [(set (match_operand 0 "register_operand" "=df")
9303 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9304 (match_operand 2 "" "i")))
9305 (clobber (match_operand:SI 3 "register_operand" "=d"))]
9306 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9307 "*
9308 {
9309 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9310 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9311 else
9312 return \"jal\\t%3,%1\";
9313 }"
9314 [(set_attr "type" "call")
9315 (set_attr "mode" "none")
9316 (set_attr "length" "2")])
9317
9318 (define_expand "call_value_multiple_internal0"
9319 [(parallel [(set (match_operand 0 "" "")
9320 (call (match_operand 1 "" "")
9321 (match_operand 2 "" "")))
9322 (set (match_operand 3 "" "")
9323 (call (match_dup 1)
9324 (match_dup 2)))
9325 (clobber (match_operand:SI 4 "" ""))])]
9326 ""
9327 "")
9328
9329 ;; ??? May eventually need all 6 versions of the call patterns with multiple
9330 ;; return values.
9331
9332 (define_insn "call_value_multiple_internal2"
9333 [(set (match_operand 0 "register_operand" "=df")
9334 (call (mem (match_operand 1 "call_insn_operand" "ri"))
9335 (match_operand 2 "" "i")))
9336 (set (match_operand 3 "register_operand" "=df")
9337 (call (mem (match_dup 1))
9338 (match_dup 2)))
9339 (clobber (match_operand:SI 4 "register_operand" "=d"))]
9340 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9341 "*
9342 {
9343 register rtx target = operands[1];
9344
9345 if (GET_CODE (target) == SYMBOL_REF)
9346 {
9347 if (GET_MODE (target) == SImode)
9348 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9349 else
9350 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9351 }
9352 else if (GET_CODE (target) == CONST_INT)
9353 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
9354 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9355 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
9356 else
9357 return \"jal\\t%4,%1\";
9358 }"
9359 [(set_attr "type" "call")
9360 (set_attr "mode" "none")
9361 (set_attr "length" "2")])
9362
9363
9364 ;; Call subroutine returning any type.
9365
9366 (define_expand "untyped_call"
9367 [(parallel [(call (match_operand 0 "" "")
9368 (const_int 0))
9369 (match_operand 1 "" "")
9370 (match_operand 2 "" "")])]
9371 ""
9372 "
9373 {
9374 if (operands[0]) /* silence statement not reached warnings */
9375 {
9376 int i;
9377
9378 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
9379
9380 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9381 {
9382 rtx set = XVECEXP (operands[2], 0, i);
9383 emit_move_insn (SET_DEST (set), SET_SRC (set));
9384 }
9385
9386 emit_insn (gen_blockage ());
9387 DONE;
9388 }
9389 }")
9390 \f
9391 ;;
9392 ;; ....................
9393 ;;
9394 ;; MISC.
9395 ;;
9396 ;; ....................
9397 ;;
9398
9399 (define_insn "nop"
9400 [(const_int 0)]
9401 ""
9402 "%(nop%)"
9403 [(set_attr "type" "nop")
9404 (set_attr "mode" "none")
9405 (set_attr "length" "1")])
9406
9407 ;; The MIPS chip does not seem to require stack probes.
9408 ;;
9409 ;; (define_expand "probe"
9410 ;; [(set (match_dup 0)
9411 ;; (match_dup 1))]
9412 ;; ""
9413 ;; "
9414 ;; {
9415 ;; operands[0] = gen_reg_rtx (SImode);
9416 ;; operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
9417 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
9418 ;;
9419 ;; /* fall through and generate default code */
9420 ;; }")
9421 ;;
9422 \f
9423 ;;
9424 ;; MIPS4 Conditional move instructions.
9425
9426 (define_insn ""
9427 [(set (match_operand:SI 0 "register_operand" "=d,d")
9428 (if_then_else:SI
9429 (match_operator 4 "equality_op"
9430 [(match_operand:SI 1 "register_operand" "d,d")
9431 (const_int 0)])
9432 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9433 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9434 "mips_isa >= 4"
9435 "@
9436 mov%B4\\t%0,%z2,%1
9437 mov%b4\\t%0,%z3,%1"
9438 [(set_attr "type" "move")
9439 (set_attr "mode" "SI")])
9440
9441 (define_insn ""
9442 [(set (match_operand:SI 0 "register_operand" "=d,d")
9443 (if_then_else:SI
9444 (match_operator 4 "equality_op"
9445 [(match_operand:DI 1 "se_register_operand" "d,d")
9446 (const_int 0)])
9447 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9448 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9449 "mips_isa >= 4"
9450 "@
9451 mov%B4\\t%0,%z2,%1
9452 mov%b4\\t%0,%z3,%1"
9453 [(set_attr "type" "move")
9454 (set_attr "mode" "SI")])
9455
9456 (define_insn ""
9457 [(set (match_operand:SI 0 "register_operand" "=d,d")
9458 (if_then_else:SI
9459 (match_operator 3 "equality_op" [(match_operand:CC 4
9460 "register_operand"
9461 "z,z")
9462 (const_int 0)])
9463 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
9464 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
9465 "mips_isa >= 4 && TARGET_HARD_FLOAT"
9466 "@
9467 mov%T3\\t%0,%z1,%4
9468 mov%t3\\t%0,%z2,%4"
9469 [(set_attr "type" "move")
9470 (set_attr "mode" "SI")])
9471
9472 (define_insn ""
9473 [(set (match_operand:DI 0 "register_operand" "=d,d")
9474 (if_then_else:DI
9475 (match_operator 4 "equality_op"
9476 [(match_operand:SI 1 "register_operand" "d,d")
9477 (const_int 0)])
9478 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
9479 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
9480 "mips_isa >= 4"
9481 "@
9482 mov%B4\\t%0,%z2,%1
9483 mov%b4\\t%0,%z3,%1"
9484 [(set_attr "type" "move")
9485 (set_attr "mode" "DI")])
9486
9487 (define_insn ""
9488 [(set (match_operand:DI 0 "register_operand" "=d,d")
9489 (if_then_else:DI
9490 (match_operator 4 "equality_op"
9491 [(match_operand:DI 1 "se_register_operand" "d,d")
9492 (const_int 0)])
9493 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
9494 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
9495 "mips_isa >= 4"
9496 "@
9497 mov%B4\\t%0,%z2,%1
9498 mov%b4\\t%0,%z3,%1"
9499 [(set_attr "type" "move")
9500 (set_attr "mode" "DI")])
9501
9502 (define_insn ""
9503 [(set (match_operand:DI 0 "register_operand" "=d,d")
9504 (if_then_else:DI
9505 (match_operator 3 "equality_op" [(match_operand:CC 4
9506 "register_operand"
9507 "z,z")
9508 (const_int 0)])
9509 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
9510 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
9511 "mips_isa >= 4 && TARGET_HARD_FLOAT"
9512 "@
9513 mov%T3\\t%0,%z1,%4
9514 mov%t3\\t%0,%z2,%4"
9515 [(set_attr "type" "move")
9516 (set_attr "mode" "DI")])
9517
9518 (define_insn ""
9519 [(set (match_operand:SF 0 "register_operand" "=f,f")
9520 (if_then_else:SF
9521 (match_operator 4 "equality_op"
9522 [(match_operand:SI 1 "register_operand" "d,d")
9523 (const_int 0)])
9524 (match_operand:SF 2 "register_operand" "f,0")
9525 (match_operand:SF 3 "register_operand" "0,f")))]
9526 "mips_isa >= 4 && TARGET_HARD_FLOAT"
9527 "@
9528 mov%B4.s\\t%0,%2,%1
9529 mov%b4.s\\t%0,%3,%1"
9530 [(set_attr "type" "move")
9531 (set_attr "mode" "SF")])
9532
9533 (define_insn ""
9534 [(set (match_operand:SF 0 "register_operand" "=f,f")
9535 (if_then_else:SF
9536 (match_operator 3 "equality_op" [(match_operand:CC 4
9537 "register_operand"
9538 "z,z")
9539 (const_int 0)])
9540 (match_operand:SF 1 "register_operand" "f,0")
9541 (match_operand:SF 2 "register_operand" "0,f")))]
9542 "mips_isa >= 4 && TARGET_HARD_FLOAT"
9543 "@
9544 mov%T3.s\\t%0,%1,%4
9545 mov%t3.s\\t%0,%2,%4"
9546 [(set_attr "type" "move")
9547 (set_attr "mode" "SF")])
9548
9549 (define_insn ""
9550 [(set (match_operand:DF 0 "register_operand" "=f,f")
9551 (if_then_else:DF
9552 (match_operator 4 "equality_op"
9553 [(match_operand:SI 1 "register_operand" "d,d")
9554 (const_int 0)])
9555 (match_operand:DF 2 "register_operand" "f,0")
9556 (match_operand:DF 3 "register_operand" "0,f")))]
9557 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9558 "@
9559 mov%B4.d\\t%0,%2,%1
9560 mov%b4.d\\t%0,%3,%1"
9561 [(set_attr "type" "move")
9562 (set_attr "mode" "DF")])
9563
9564 (define_insn ""
9565 [(set (match_operand:DF 0 "register_operand" "=f,f")
9566 (if_then_else:DF
9567 (match_operator 3 "equality_op" [(match_operand:CC 4
9568 "register_operand"
9569 "z,z")
9570 (const_int 0)])
9571 (match_operand:DF 1 "register_operand" "f,0")
9572 (match_operand:DF 2 "register_operand" "0,f")))]
9573 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9574 "@
9575 mov%T3.d\\t%0,%1,%4
9576 mov%t3.d\\t%0,%2,%4"
9577 [(set_attr "type" "move")
9578 (set_attr "mode" "DF")])
9579
9580 ;; These are the main define_expand's used to make conditional moves.
9581
9582 (define_expand "movsicc"
9583 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9584 (set (match_operand:SI 0 "register_operand" "")
9585 (if_then_else:SI (match_dup 5)
9586 (match_operand:SI 2 "reg_or_0_operand" "")
9587 (match_operand:SI 3 "reg_or_0_operand" "")))]
9588 "mips_isa >= 4"
9589 "
9590 {
9591 gen_conditional_move (operands);
9592 DONE;
9593 }")
9594
9595 (define_expand "movdicc"
9596 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9597 (set (match_operand:DI 0 "register_operand" "")
9598 (if_then_else:DI (match_dup 5)
9599 (match_operand:DI 2 "se_reg_or_0_operand" "")
9600 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
9601 "mips_isa >= 4"
9602 "
9603 {
9604 gen_conditional_move (operands);
9605 DONE;
9606 }")
9607
9608 (define_expand "movsfcc"
9609 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9610 (set (match_operand:SF 0 "register_operand" "")
9611 (if_then_else:SF (match_dup 5)
9612 (match_operand:SF 2 "register_operand" "")
9613 (match_operand:SF 3 "register_operand" "")))]
9614 "mips_isa >= 4 && TARGET_HARD_FLOAT"
9615 "
9616 {
9617 gen_conditional_move (operands);
9618 DONE;
9619 }")
9620
9621 (define_expand "movdfcc"
9622 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9623 (set (match_operand:DF 0 "register_operand" "")
9624 (if_then_else:DF (match_dup 5)
9625 (match_operand:DF 2 "register_operand" "")
9626 (match_operand:DF 3 "register_operand" "")))]
9627 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9628 "
9629 {
9630 gen_conditional_move (operands);
9631 DONE;
9632 }")
9633 \f
9634 ;;
9635 ;; ....................
9636 ;;
9637 ;; mips16 inline constant tables
9638 ;;
9639 ;; ....................
9640 ;;
9641
9642 (define_insn "consttable_qi"
9643 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
9644 "TARGET_MIPS16"
9645 "*
9646 {
9647 assemble_integer (operands[0], 1, 1);
9648 return \"\";
9649 }"
9650 [(set_attr "type" "unknown")
9651 (set_attr "mode" "QI")
9652 (set_attr "length" "2")])
9653
9654 (define_insn "consttable_hi"
9655 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
9656 "TARGET_MIPS16"
9657 "*
9658 {
9659 assemble_integer (operands[0], 2, 1);
9660 return \"\";
9661 }"
9662 [(set_attr "type" "unknown")
9663 (set_attr "mode" "HI")
9664 (set_attr "length" "2")])
9665
9666 (define_insn "consttable_si"
9667 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
9668 "TARGET_MIPS16"
9669 "*
9670 {
9671 assemble_integer (operands[0], 4, 1);
9672 return \"\";
9673 }"
9674 [(set_attr "type" "unknown")
9675 (set_attr "mode" "SI")
9676 (set_attr "length" "2")])
9677
9678 (define_insn "consttable_di"
9679 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
9680 "TARGET_MIPS16"
9681 "*
9682 {
9683 assemble_integer (operands[0], 8, 1);
9684 return \"\";
9685 }"
9686 [(set_attr "type" "unknown")
9687 (set_attr "mode" "DI")
9688 (set_attr "length" "4")])
9689
9690 (define_insn "consttable_sf"
9691 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
9692 "TARGET_MIPS16"
9693 "*
9694 {
9695 union real_extract u;
9696
9697 if (GET_CODE (operands[0]) != CONST_DOUBLE)
9698 abort ();
9699 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
9700 assemble_real (u.d, SFmode);
9701 return \"\";
9702 }"
9703 [(set_attr "type" "unknown")
9704 (set_attr "mode" "SF")
9705 (set_attr "length" "2")])
9706
9707 (define_insn "consttable_df"
9708 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
9709 "TARGET_MIPS16"
9710 "*
9711 {
9712 union real_extract u;
9713
9714 if (GET_CODE (operands[0]) != CONST_DOUBLE)
9715 abort ();
9716 bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
9717 assemble_real (u.d, DFmode);
9718 return \"\";
9719 }"
9720 [(set_attr "type" "unknown")
9721 (set_attr "mode" "DF")
9722 (set_attr "length" "4")])
9723
9724 (define_insn "align_2"
9725 [(unspec_volatile [(const_int 0)] 16)]
9726 "TARGET_MIPS16"
9727 ".align 1"
9728 [(set_attr "type" "unknown")
9729 (set_attr "mode" "HI")
9730 (set_attr "length" "2")])
9731
9732 (define_insn "align_4"
9733 [(unspec_volatile [(const_int 0)] 17)]
9734 "TARGET_MIPS16"
9735 ".align 2"
9736 [(set_attr "type" "unknown")
9737 (set_attr "mode" "SI")
9738 (set_attr "length" "2")])
9739
9740 (define_insn "align_8"
9741 [(unspec_volatile [(const_int 0)] 18)]
9742 "TARGET_MIPS16"
9743 ".align 3"
9744 [(set_attr "type" "unknown")
9745 (set_attr "mode" "DI")
9746 (set_attr "length" "3")])
9747 \f
9748 ;;
9749 ;; ....................
9750 ;;
9751 ;; mips16 peepholes
9752 ;;
9753 ;; ....................
9754 ;;
9755
9756 ;; On the mips16, reload will sometimes decide that a pseudo register
9757 ;; should go into $24, and then later on have to reload that register.
9758 ;; When that happens, we get a load of a general register followed by
9759 ;; a move from the general register to $24 followed by a branch.
9760 ;; These peepholes catch the common case, and fix it to just use the
9761 ;; general register for the branch.
9762
9763 (define_peephole
9764 [(set (match_operand:SI 0 "register_operand" "=t")
9765 (match_operand:SI 1 "register_operand" "d"))
9766 (set (pc)
9767 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
9768 (const_int 0)])
9769 (match_operand 3 "pc_or_label_operand" "")
9770 (match_operand 4 "pc_or_label_operand" "")))]
9771 "TARGET_MIPS16
9772 && GET_CODE (operands[0]) == REG
9773 && REGNO (operands[0]) == 24
9774 && dead_or_set_p (insn, operands[0])
9775 && GET_CODE (operands[1]) == REG
9776 && M16_REG_P (REGNO (operands[1]))"
9777 "*
9778 {
9779 if (operands[3] != pc_rtx)
9780 return \"%*b%C2z\\t%1,%3\";
9781 else
9782 return \"%*b%N2z\\t%1,%4\";
9783 }"
9784 [(set_attr "type" "branch")
9785 (set_attr "mode" "none")
9786 (set_attr "length" "2")])
9787
9788 (define_peephole
9789 [(set (match_operand:DI 0 "register_operand" "=t")
9790 (match_operand:DI 1 "register_operand" "d"))
9791 (set (pc)
9792 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9793 (const_int 0)])
9794 (match_operand 3 "pc_or_label_operand" "")
9795 (match_operand 4 "pc_or_label_operand" "")))]
9796 "TARGET_MIPS16 && TARGET_64BIT
9797 && GET_CODE (operands[0]) == REG
9798 && REGNO (operands[0]) == 24
9799 && dead_or_set_p (insn, operands[0])
9800 && GET_CODE (operands[1]) == REG
9801 && M16_REG_P (REGNO (operands[1]))"
9802 "*
9803 {
9804 if (operands[3] != pc_rtx)
9805 return \"%*b%C2z\\t%1,%3\";
9806 else
9807 return \"%*b%N2z\\t%1,%4\";
9808 }"
9809 [(set_attr "type" "branch")
9810 (set_attr "mode" "none")
9811 (set_attr "length" "2")])
9812
9813 ;; We can also have the reverse reload: reload will spill $24 into
9814 ;; another register, and then do a branch on that register when it
9815 ;; could have just stuck with $24.
9816
9817 (define_peephole
9818 [(set (match_operand:SI 0 "register_operand" "=d")
9819 (match_operand:SI 1 "register_operand" "t"))
9820 (set (pc)
9821 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
9822 (const_int 0)])
9823 (match_operand 3 "pc_or_label_operand" "")
9824 (match_operand 4 "pc_or_label_operand" "")))]
9825 "TARGET_MIPS16
9826 && GET_CODE (operands[1]) == REG
9827 && REGNO (operands[1]) == 24
9828 && GET_CODE (operands[0]) == REG
9829 && M16_REG_P (REGNO (operands[0]))
9830 && dead_or_set_p (insn, operands[0])"
9831 "*
9832 {
9833 if (operands[3] != pc_rtx)
9834 return \"%*bt%C2z\\t%3\";
9835 else
9836 return \"%*bt%N2z\\t%4\";
9837 }"
9838 [(set_attr "type" "branch")
9839 (set_attr "mode" "none")
9840 (set_attr "length" "2")])
9841
9842 (define_peephole
9843 [(set (match_operand:DI 0 "register_operand" "=d")
9844 (match_operand:DI 1 "register_operand" "t"))
9845 (set (pc)
9846 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9847 (const_int 0)])
9848 (match_operand 3 "pc_or_label_operand" "")
9849 (match_operand 4 "pc_or_label_operand" "")))]
9850 "TARGET_MIPS16 && TARGET_64BIT
9851 && GET_CODE (operands[1]) == REG
9852 && REGNO (operands[1]) == 24
9853 && GET_CODE (operands[0]) == REG
9854 && M16_REG_P (REGNO (operands[0]))
9855 && dead_or_set_p (insn, operands[0])"
9856 "*
9857 {
9858 if (operands[3] != pc_rtx)
9859 return \"%*bt%C2z\\t%3\";
9860 else
9861 return \"%*bt%N2z\\t%4\";
9862 }"
9863 [(set_attr "type" "branch")
9864 (set_attr "mode" "none")
9865 (set_attr "length" "2")])
This page took 0.584436 seconds and 5 git commands to generate.