]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mips/mips.md
Merge from gcc-2.8
[thirdparty/gcc.git] / gcc / config / mips / mips.md
1 ;; Mips.md Machine Description for MIPS based processors
2 ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
3 ;; Changes by Michael Meissner, meissner@osf.org
4 ;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
5 ;; Brendan Eich, brendan@microunity.com.
6 ;; Copyright (C) 1989, 90-96, 1997 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 (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp")
75 (const_string "yes")
76 (const_string "no")))
77
78 ;; Attribute describing the processor. This attribute must match exactly
79 ;; with the processor_type enumeration in mips.h.
80
81 ;; Attribute describing the processor
82 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
83 ;; (const
84 ;; (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000")) (const_string "r3000")
85 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000")) (const_string "r4000")
86 ;; (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000")) (const_string "r6000")]
87 ;; (const_string "default"))))
88
89 ;; ??? Fix everything that tests this attribute.
90 (define_attr "cpu"
91 "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
92 (const (symbol_ref "mips_cpu_attr")))
93
94 ;; Attribute defining whether or not we can use the branch-likely instructions
95
96 (define_attr "branch_likely" "no,yes"
97 (const
98 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
99 (const_string "yes")
100 (const_string "no"))))
101
102
103 ;; Describe a user's asm statement.
104 (define_asm_attributes
105 [(set_attr "type" "multi")])
106
107 ;; whether or not generating calls to position independent functions
108 (define_attr "abicalls" "no,yes"
109 (const (symbol_ref "mips_abicalls_attr")))
110
111 \f
112
113 ;; .........................
114 ;;
115 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
116 ;;
117 ;; .........................
118
119 (define_delay (eq_attr "type" "branch")
120 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
121 (nil)
122 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
123
124 (define_delay (eq_attr "type" "jump")
125 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
126 (nil)
127 (nil)])
128
129 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
130 [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
131 (nil)
132 (nil)])
133
134 \f
135
136 ;; .........................
137 ;;
138 ;; Functional units
139 ;;
140 ;; .........................
141
142 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
143 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
144
145 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
146
147 (define_function_unit "memory" 1 0
148 (and (eq_attr "type" "load")
149 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
150 3 0)
151
152 (define_function_unit "memory" 1 0
153 (and (eq_attr "type" "load")
154 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
155 2 0)
156
157 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
158
159 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
160
161 (define_function_unit "imuldiv" 1 0
162 (eq_attr "type" "hilo")
163 1 3)
164
165 (define_function_unit "imuldiv" 1 0
166 (and (eq_attr "type" "imul")
167 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
168 17 17)
169
170 (define_function_unit "imuldiv" 1 0
171 (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
172 12 12)
173
174 (define_function_unit "imuldiv" 1 0
175 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
176 10 10)
177
178 (define_function_unit "imuldiv" 1 0
179 (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
180 4 4)
181
182 (define_function_unit "imuldiv" 1 0
183 (and (eq_attr "type" "imul")
184 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
185 1 1)
186
187 (define_function_unit "imuldiv" 1 0
188 (and (eq_attr "type" "imul")
189 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
190 4 4)
191
192 (define_function_unit "imuldiv" 1 0
193 (and (eq_attr "type" "imul")
194 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
195 5 5)
196
197 (define_function_unit "imuldiv" 1 0
198 (and (eq_attr "type" "imul")
199 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
200 8 8)
201
202 (define_function_unit "imuldiv" 1 0
203 (and (eq_attr "type" "imul")
204 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
205 9 9)
206
207 (define_function_unit "imuldiv" 1 0
208 (and (eq_attr "type" "idiv")
209 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
210 38 38)
211
212 (define_function_unit "imuldiv" 1 0
213 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
214 35 35)
215
216 (define_function_unit "imuldiv" 1 0
217 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
218 42 42)
219
220 (define_function_unit "imuldiv" 1 0
221 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
222 36 36)
223
224 (define_function_unit "imuldiv" 1 0
225 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
226 69 69)
227
228 (define_function_unit "imuldiv" 1 0
229 (and (eq_attr "type" "idiv")
230 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
231 35 35)
232
233 (define_function_unit "imuldiv" 1 0
234 (and (eq_attr "type" "idiv")
235 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
236 67 67)
237
238 (define_function_unit "imuldiv" 1 0
239 (and (eq_attr "type" "idiv")
240 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
241 37 37)
242
243 (define_function_unit "imuldiv" 1 0
244 (and (eq_attr "type" "idiv")
245 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
246 69 69)
247
248 (define_function_unit "imuldiv" 1 0
249 (and (eq_attr "type" "idiv")
250 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
251 36 36)
252
253 (define_function_unit "imuldiv" 1 0
254 (and (eq_attr "type" "idiv")
255 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
256 68 68)
257
258 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
259 ;; the FP hardware is part of the normal ALU circuitry. This means FP
260 ;; instructions affect the pipe-line, and no functional unit
261 ;; parallelism can occur on R4300 processors. To force GCC into coding
262 ;; for only a single functional unit, we force the R4300 FP
263 ;; instructions to be processed in the "imuldiv" unit.
264
265 (define_function_unit "adder" 1 1
266 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
267 3 0)
268
269 (define_function_unit "adder" 1 1
270 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
271 2 0)
272
273 (define_function_unit "adder" 1 1
274 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
275 1 0)
276
277 (define_function_unit "adder" 1 1
278 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
279 4 0)
280
281 (define_function_unit "adder" 1 1
282 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
283 2 0)
284
285 (define_function_unit "adder" 1 1
286 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
287 3 0)
288
289 (define_function_unit "adder" 1 1
290 (and (eq_attr "type" "fabs,fneg")
291 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
292 2 0)
293
294 (define_function_unit "adder" 1 1
295 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
296 1 0)
297
298 (define_function_unit "mult" 1 1
299 (and (eq_attr "type" "fmul")
300 (and (eq_attr "mode" "SF")
301 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
302 7 0)
303
304 (define_function_unit "mult" 1 1
305 (and (eq_attr "type" "fmul")
306 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
307 4 0)
308
309 (define_function_unit "mult" 1 1
310 (and (eq_attr "type" "fmul")
311 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
312 5 0)
313
314 (define_function_unit "mult" 1 1
315 (and (eq_attr "type" "fmul")
316 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
317 8 0)
318
319 (define_function_unit "mult" 1 1
320 (and (eq_attr "type" "fmul")
321 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
322 8 0)
323
324 (define_function_unit "mult" 1 1
325 (and (eq_attr "type" "fmul")
326 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
327 5 0)
328
329 (define_function_unit "mult" 1 1
330 (and (eq_attr "type" "fmul")
331 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
332 6 0)
333
334 (define_function_unit "divide" 1 1
335 (and (eq_attr "type" "fdiv")
336 (and (eq_attr "mode" "SF")
337 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
338 23 0)
339
340 (define_function_unit "divide" 1 1
341 (and (eq_attr "type" "fdiv")
342 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
343 12 0)
344
345 (define_function_unit "divide" 1 1
346 (and (eq_attr "type" "fdiv")
347 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
348 15 0)
349
350 (define_function_unit "divide" 1 1
351 (and (eq_attr "type" "fdiv")
352 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
353 32 0)
354
355 (define_function_unit "divide" 1 1
356 (and (eq_attr "type" "fdiv")
357 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
358 21 0)
359
360 (define_function_unit "divide" 1 1
361 (and (eq_attr "type" "fdiv")
362 (and (eq_attr "mode" "DF")
363 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
364 36 0)
365
366 (define_function_unit "divide" 1 1
367 (and (eq_attr "type" "fdiv")
368 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
369 19 0)
370
371 (define_function_unit "divide" 1 1
372 (and (eq_attr "type" "fdiv")
373 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
374 16 0)
375
376 (define_function_unit "divide" 1 1
377 (and (eq_attr "type" "fdiv")
378 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
379 61 0)
380
381 ;;; ??? Is this number right?
382 (define_function_unit "divide" 1 1
383 (and (eq_attr "type" "fsqrt")
384 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
385 54 0)
386
387 (define_function_unit "divide" 1 1
388 (and (eq_attr "type" "fsqrt")
389 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
390 31 0)
391
392 (define_function_unit "divide" 1 1
393 (and (eq_attr "type" "fsqrt")
394 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
395 21 0)
396
397 ;;; ??? Is this number right?
398 (define_function_unit "divide" 1 1
399 (and (eq_attr "type" "fsqrt")
400 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
401 112 0)
402
403 (define_function_unit "divide" 1 1
404 (and (eq_attr "type" "fsqrt")
405 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
406 60 0)
407
408 (define_function_unit "divide" 1 1
409 (and (eq_attr "type" "fsqrt")
410 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
411 36 0)
412
413 ;; R4300 FP instruction classes treated as part of the "imuldiv"
414 ;; functional unit:
415
416 (define_function_unit "imuldiv" 1 0
417 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
418 3 3)
419
420 (define_function_unit "imuldiv" 1 0
421 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
422 1 1)
423
424 (define_function_unit "imuldiv" 1 0
425 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
426 5 5)
427 (define_function_unit "imuldiv" 1 0
428 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
429 8 8)
430
431 (define_function_unit "imuldiv" 1 0
432 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
433 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
434 29 29)
435 (define_function_unit "imuldiv" 1 0
436 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
437 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
438 58 58)
439 \f
440 ;; The following functional units do not use the cpu type, and use
441 ;; much less memory in genattrtab.c.
442
443 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "load") 3 0)
444 ;; (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
445 ;;
446 ;; (define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
447 ;;
448 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
449 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
450 ;;
451 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "imul") 17 0)
452 ;; (define_function_unit "imuldiv" 1 1 (eq_attr "type" "idiv") 38 0)
453 ;;
454 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fadd") 4 0)
455 ;; (define_function_unit "adder" 1 1 (eq_attr "type" "fabs,fneg") 2 0)
456 ;;
457 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF")) 7 0)
458 ;; (define_function_unit "mult" 1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF")) 8 0)
459 ;;
460 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF")) 23 0)
461 ;; (define_function_unit "divide" 1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF")) 36 0)
462 ;;
463 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF")) 54 0)
464 ;; (define_function_unit "sqrt" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
465
466 \f
467 ;;
468 ;; ....................
469 ;;
470 ;; ADDITION
471 ;;
472 ;; ....................
473 ;;
474
475 (define_insn "adddf3"
476 [(set (match_operand:DF 0 "register_operand" "=f")
477 (plus:DF (match_operand:DF 1 "register_operand" "f")
478 (match_operand:DF 2 "register_operand" "f")))]
479 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
480 "add.d\\t%0,%1,%2"
481 [(set_attr "type" "fadd")
482 (set_attr "mode" "DF")
483 (set_attr "length" "1")])
484
485 (define_insn "addsf3"
486 [(set (match_operand:SF 0 "register_operand" "=f")
487 (plus:SF (match_operand:SF 1 "register_operand" "f")
488 (match_operand:SF 2 "register_operand" "f")))]
489 "TARGET_HARD_FLOAT"
490 "add.s\\t%0,%1,%2"
491 [(set_attr "type" "fadd")
492 (set_attr "mode" "SF")
493 (set_attr "length" "1")])
494
495 (define_expand "addsi3"
496 [(set (match_operand:SI 0 "register_operand" "=d")
497 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
498 (match_operand:SI 2 "arith_operand" "dI")))]
499 ""
500 "
501 {
502 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
503 operands[2] = force_reg (SImode, operands[2]);
504 }")
505
506 (define_insn "addsi3_internal"
507 [(set (match_operand:SI 0 "register_operand" "=d")
508 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
509 (match_operand:SI 2 "arith_operand" "dI")))]
510 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
511 "addu\\t%0,%z1,%2"
512 [(set_attr "type" "arith")
513 (set_attr "mode" "SI")
514 (set_attr "length" "1")])
515
516 (define_expand "adddi3"
517 [(parallel [(set (match_operand:DI 0 "register_operand" "")
518 (plus:DI (match_operand:DI 1 "se_register_operand" "")
519 (match_operand:DI 2 "se_arith_operand" "")))
520 (clobber (match_dup 3))])]
521 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
522 "
523 {
524 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
525 operands[2] = force_reg (DImode, operands[2]);
526
527 if (TARGET_64BIT)
528 {
529 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
530 operands[2]));
531 DONE;
532 }
533
534 operands[3] = gen_reg_rtx (SImode);
535 }")
536
537 (define_insn "adddi3_internal_1"
538 [(set (match_operand:DI 0 "register_operand" "=d,&d")
539 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
540 (match_operand:DI 2 "register_operand" "d,d")))
541 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
542 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
543 "*
544 {
545 return (REGNO (operands[0]) == REGNO (operands[1])
546 && REGNO (operands[0]) == REGNO (operands[2]))
547 ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
548 : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
549 }"
550 [(set_attr "type" "darith")
551 (set_attr "mode" "DI")
552 (set_attr "length" "4")])
553
554 (define_split
555 [(set (match_operand:DI 0 "register_operand" "")
556 (plus:DI (match_operand:DI 1 "register_operand" "")
557 (match_operand:DI 2 "register_operand" "")))
558 (clobber (match_operand:SI 3 "register_operand" ""))]
559 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
560 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
561 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
562 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
563 && (REGNO (operands[0]) != REGNO (operands[1])
564 || REGNO (operands[0]) != REGNO (operands[2]))"
565
566 [(set (subreg:SI (match_dup 0) 0)
567 (plus:SI (subreg:SI (match_dup 1) 0)
568 (subreg:SI (match_dup 2) 0)))
569
570 (set (match_dup 3)
571 (ltu:SI (subreg:SI (match_dup 0) 0)
572 (subreg:SI (match_dup 2) 0)))
573
574 (set (subreg:SI (match_dup 0) 1)
575 (plus:SI (subreg:SI (match_dup 1) 1)
576 (subreg:SI (match_dup 2) 1)))
577
578 (set (subreg:SI (match_dup 0) 1)
579 (plus:SI (subreg:SI (match_dup 0) 1)
580 (match_dup 3)))]
581 "")
582
583 (define_split
584 [(set (match_operand:DI 0 "register_operand" "")
585 (plus:DI (match_operand:DI 1 "register_operand" "")
586 (match_operand:DI 2 "register_operand" "")))
587 (clobber (match_operand:SI 3 "register_operand" ""))]
588 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
589 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
590 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
591 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
592 && (REGNO (operands[0]) != REGNO (operands[1])
593 || REGNO (operands[0]) != REGNO (operands[2]))"
594
595 [(set (subreg:SI (match_dup 0) 1)
596 (plus:SI (subreg:SI (match_dup 1) 1)
597 (subreg:SI (match_dup 2) 1)))
598
599 (set (match_dup 3)
600 (ltu:SI (subreg:SI (match_dup 0) 1)
601 (subreg:SI (match_dup 2) 1)))
602
603 (set (subreg:SI (match_dup 0) 0)
604 (plus:SI (subreg:SI (match_dup 1) 0)
605 (subreg:SI (match_dup 2) 0)))
606
607 (set (subreg:SI (match_dup 0) 0)
608 (plus:SI (subreg:SI (match_dup 0) 0)
609 (match_dup 3)))]
610 "")
611
612 (define_insn "adddi3_internal_2"
613 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
614 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
615 (match_operand:DI 2 "small_int" "P,J,N")))
616 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
617 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
618 "@
619 addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
620 move\\t%L0,%L1\;move\\t%M0,%M1
621 subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
622 [(set_attr "type" "darith")
623 (set_attr "mode" "DI")
624 (set_attr "length" "3,2,4")])
625
626 (define_split
627 [(set (match_operand:DI 0 "register_operand" "")
628 (plus:DI (match_operand:DI 1 "register_operand" "")
629 (match_operand:DI 2 "small_int" "")))
630 (clobber (match_operand:SI 3 "register_operand" "=d"))]
631 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
632 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
633 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
634 && INTVAL (operands[2]) > 0"
635
636 [(set (subreg:SI (match_dup 0) 0)
637 (plus:SI (subreg:SI (match_dup 1) 0)
638 (match_dup 2)))
639
640 (set (match_dup 3)
641 (ltu:SI (subreg:SI (match_dup 0) 0)
642 (match_dup 2)))
643
644 (set (subreg:SI (match_dup 0) 1)
645 (plus:SI (subreg:SI (match_dup 1) 1)
646 (match_dup 3)))]
647 "")
648
649 (define_split
650 [(set (match_operand:DI 0 "register_operand" "")
651 (plus:DI (match_operand:DI 1 "register_operand" "")
652 (match_operand:DI 2 "small_int" "")))
653 (clobber (match_operand:SI 3 "register_operand" "=d"))]
654 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
655 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
656 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
657 && INTVAL (operands[2]) > 0"
658
659 [(set (subreg:SI (match_dup 0) 1)
660 (plus:SI (subreg:SI (match_dup 1) 1)
661 (match_dup 2)))
662
663 (set (match_dup 3)
664 (ltu:SI (subreg:SI (match_dup 0) 1)
665 (match_dup 2)))
666
667 (set (subreg:SI (match_dup 0) 0)
668 (plus:SI (subreg:SI (match_dup 1) 0)
669 (match_dup 3)))]
670 "")
671
672 (define_insn "adddi3_internal_3"
673 [(set (match_operand:DI 0 "register_operand" "=d")
674 (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
675 (match_operand:DI 2 "se_arith_operand" "dI")))]
676 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
677 "*
678 {
679 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
680 ? \"dsubu\\t%0,%z1,%n2\"
681 : \"daddu\\t%0,%z1,%2\";
682 }"
683 [(set_attr "type" "darith")
684 (set_attr "mode" "DI")
685 (set_attr "length" "1")])
686
687
688 (define_insn "addsi3_internal_2"
689 [(set (match_operand:DI 0 "register_operand" "=d")
690 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
691 (match_operand:SI 2 "arith_operand" "dI"))))]
692 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
693 "*
694 {
695 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
696 ? \"subu\\t%0,%z1,%n2\"
697 : \"addu\\t%0,%z1,%2\";
698 }"
699 [(set_attr "type" "arith")
700 (set_attr "mode" "SI")
701 (set_attr "length" "1")])
702
703 \f
704 ;;
705 ;; ....................
706 ;;
707 ;; SUBTRACTION
708 ;;
709 ;; ....................
710 ;;
711
712 (define_insn "subdf3"
713 [(set (match_operand:DF 0 "register_operand" "=f")
714 (minus:DF (match_operand:DF 1 "register_operand" "f")
715 (match_operand:DF 2 "register_operand" "f")))]
716 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
717 "sub.d\\t%0,%1,%2"
718 [(set_attr "type" "fadd")
719 (set_attr "mode" "DF")
720 (set_attr "length" "1")])
721
722 (define_insn "subsf3"
723 [(set (match_operand:SF 0 "register_operand" "=f")
724 (minus:SF (match_operand:SF 1 "register_operand" "f")
725 (match_operand:SF 2 "register_operand" "f")))]
726 "TARGET_HARD_FLOAT"
727 "sub.s\\t%0,%1,%2"
728 [(set_attr "type" "fadd")
729 (set_attr "mode" "SF")
730 (set_attr "length" "1")])
731
732 (define_expand "subsi3"
733 [(set (match_operand:SI 0 "register_operand" "=d")
734 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
735 (match_operand:SI 2 "arith_operand" "dI")))]
736 ""
737 "
738 {
739 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
740 operands[2] = force_reg (SImode, operands[2]);
741 }")
742
743 (define_insn "subsi3_internal"
744 [(set (match_operand:SI 0 "register_operand" "=d")
745 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
746 (match_operand:SI 2 "arith_operand" "dI")))]
747 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
748 "subu\\t%0,%z1,%2"
749 [(set_attr "type" "arith")
750 (set_attr "mode" "SI")
751 (set_attr "length" "1")])
752
753 (define_expand "subdi3"
754 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
755 (minus:DI (match_operand:DI 1 "se_register_operand" "d")
756 (match_operand:DI 2 "se_register_operand" "d")))
757 (clobber (match_dup 3))])]
758 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
759 "
760 {
761 if (TARGET_64BIT)
762 {
763 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
764 operands[2]));
765 DONE;
766 }
767
768 operands[3] = gen_reg_rtx (SImode);
769 }")
770
771 (define_insn "subdi3_internal"
772 [(set (match_operand:DI 0 "register_operand" "=d")
773 (minus:DI (match_operand:DI 1 "register_operand" "d")
774 (match_operand:DI 2 "register_operand" "d")))
775 (clobber (match_operand:SI 3 "register_operand" "=d"))]
776 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
777 "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
778 [(set_attr "type" "darith")
779 (set_attr "mode" "DI")
780 (set_attr "length" "4")])
781
782 (define_split
783 [(set (match_operand:DI 0 "register_operand" "")
784 (minus:DI (match_operand:DI 1 "register_operand" "")
785 (match_operand:DI 2 "register_operand" "")))
786 (clobber (match_operand:SI 3 "register_operand" ""))]
787 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
788 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
789 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
790 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
791
792 [(set (match_dup 3)
793 (ltu:SI (subreg:SI (match_dup 1) 0)
794 (subreg:SI (match_dup 2) 0)))
795
796 (set (subreg:SI (match_dup 0) 0)
797 (minus:SI (subreg:SI (match_dup 1) 0)
798 (subreg:SI (match_dup 2) 0)))
799
800 (set (subreg:SI (match_dup 0) 1)
801 (minus:SI (subreg:SI (match_dup 1) 1)
802 (subreg:SI (match_dup 2) 1)))
803
804 (set (subreg:SI (match_dup 0) 1)
805 (minus:SI (subreg:SI (match_dup 0) 1)
806 (match_dup 3)))]
807 "")
808
809 (define_split
810 [(set (match_operand:DI 0 "register_operand" "")
811 (minus:DI (match_operand:DI 1 "register_operand" "")
812 (match_operand:DI 2 "register_operand" "")))
813 (clobber (match_operand:SI 3 "register_operand" ""))]
814 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
815 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
816 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
817 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
818
819 [(set (match_dup 3)
820 (ltu:SI (subreg:SI (match_dup 1) 1)
821 (subreg:SI (match_dup 2) 1)))
822
823 (set (subreg:SI (match_dup 0) 1)
824 (minus:SI (subreg:SI (match_dup 1) 1)
825 (subreg:SI (match_dup 2) 1)))
826
827 (set (subreg:SI (match_dup 0) 0)
828 (minus:SI (subreg:SI (match_dup 1) 0)
829 (subreg:SI (match_dup 2) 0)))
830
831 (set (subreg:SI (match_dup 0) 0)
832 (minus:SI (subreg:SI (match_dup 0) 0)
833 (match_dup 3)))]
834 "")
835
836 (define_insn "subdi3_internal_2"
837 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
838 (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
839 (match_operand:DI 2 "small_int" "P,J,N")))
840 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
841 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
842 "@
843 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
844 move\\t%L0,%L1\;move\\t%M0,%M1
845 sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
846 [(set_attr "type" "darith")
847 (set_attr "mode" "DI")
848 (set_attr "length" "3,2,4")])
849
850 (define_split
851 [(set (match_operand:DI 0 "register_operand" "")
852 (minus:DI (match_operand:DI 1 "register_operand" "")
853 (match_operand:DI 2 "small_int" "")))
854 (clobber (match_operand:SI 3 "register_operand" ""))]
855 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
856 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
857 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
858 && INTVAL (operands[2]) > 0"
859
860 [(set (match_dup 3)
861 (ltu:SI (subreg:SI (match_dup 1) 0)
862 (match_dup 2)))
863
864 (set (subreg:SI (match_dup 0) 0)
865 (minus:SI (subreg:SI (match_dup 1) 0)
866 (match_dup 2)))
867
868 (set (subreg:SI (match_dup 0) 1)
869 (minus:SI (subreg:SI (match_dup 1) 1)
870 (match_dup 3)))]
871 "")
872
873 (define_split
874 [(set (match_operand:DI 0 "register_operand" "")
875 (minus:DI (match_operand:DI 1 "register_operand" "")
876 (match_operand:DI 2 "small_int" "")))
877 (clobber (match_operand:SI 3 "register_operand" ""))]
878 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
879 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
880 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
881 && INTVAL (operands[2]) > 0"
882
883 [(set (match_dup 3)
884 (ltu:SI (subreg:SI (match_dup 1) 1)
885 (match_dup 2)))
886
887 (set (subreg:SI (match_dup 0) 1)
888 (minus:SI (subreg:SI (match_dup 1) 1)
889 (match_dup 2)))
890
891 (set (subreg:SI (match_dup 0) 0)
892 (minus:SI (subreg:SI (match_dup 1) 0)
893 (match_dup 3)))]
894 "")
895
896 (define_insn "subdi3_internal_3"
897 [(set (match_operand:DI 0 "register_operand" "=d")
898 (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
899 (match_operand:DI 2 "se_arith_operand" "dI")))]
900 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
901 "*
902 {
903 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
904 ? \"daddu\\t%0,%z1,%n2\"
905 : \"dsubu\\t%0,%z1,%2\";
906 }"
907 [(set_attr "type" "darith")
908 (set_attr "mode" "DI")
909 (set_attr "length" "1")])
910
911
912 (define_insn "subsi3_internal_2"
913 [(set (match_operand:DI 0 "register_operand" "=d")
914 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
915 (match_operand:SI 2 "arith_operand" "dI"))))]
916 "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
917 "*
918 {
919 return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
920 ? \"addu\\t%0,%z1,%n2\"
921 : \"subu\\t%0,%z1,%2\";
922 }"
923 [(set_attr "type" "arith")
924 (set_attr "mode" "DI")
925 (set_attr "length" "1")])
926
927 \f
928 ;;
929 ;; ....................
930 ;;
931 ;; MULTIPLICATION
932 ;;
933 ;; ....................
934 ;;
935
936 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
937 ;; operands may corrupt immediately following multiplies. This is a
938 ;; simple fix to insert NOPs.
939
940 (define_expand "muldf3"
941 [(set (match_operand:DF 0 "register_operand" "=f")
942 (mult:DF (match_operand:DF 1 "register_operand" "f")
943 (match_operand:DF 2 "register_operand" "f")))]
944 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
945 "
946 {
947 if (mips_cpu != PROCESSOR_R4300)
948 emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
949 else
950 emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
951 DONE;
952 }")
953
954 (define_insn "muldf3_internal"
955 [(set (match_operand:DF 0 "register_operand" "=f")
956 (mult:DF (match_operand:DF 1 "register_operand" "f")
957 (match_operand:DF 2 "register_operand" "f")))]
958 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
959 "mul.d\\t%0,%1,%2"
960 [(set_attr "type" "fmul")
961 (set_attr "mode" "DF")
962 (set_attr "length" "1")])
963
964 (define_insn "muldf3_r4300"
965 [(set (match_operand:DF 0 "register_operand" "=f")
966 (mult:DF (match_operand:DF 1 "register_operand" "f")
967 (match_operand:DF 2 "register_operand" "f")))]
968 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
969 "*
970 {
971 output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
972 if (TARGET_4300_MUL_FIX)
973 output_asm_insn (\"nop\", operands);
974 return \"\";
975 }"
976 [(set_attr "type" "fmul")
977 (set_attr "mode" "DF")
978 (set_attr "length" "2")]) ;; mul.d + nop
979
980 (define_expand "mulsf3"
981 [(set (match_operand:SF 0 "register_operand" "=f")
982 (mult:SF (match_operand:SF 1 "register_operand" "f")
983 (match_operand:SF 2 "register_operand" "f")))]
984 "TARGET_HARD_FLOAT"
985 "
986 {
987 if (mips_cpu != PROCESSOR_R4300)
988 emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
989 else
990 emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
991 DONE;
992 }")
993
994 (define_insn "mulsf3_internal"
995 [(set (match_operand:SF 0 "register_operand" "=f")
996 (mult:SF (match_operand:SF 1 "register_operand" "f")
997 (match_operand:SF 2 "register_operand" "f")))]
998 "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
999 "mul.s\\t%0,%1,%2"
1000 [(set_attr "type" "fmul")
1001 (set_attr "mode" "SF")
1002 (set_attr "length" "1")])
1003
1004 (define_insn "mulsf3_r4300"
1005 [(set (match_operand:SF 0 "register_operand" "=f")
1006 (mult:SF (match_operand:SF 1 "register_operand" "f")
1007 (match_operand:SF 2 "register_operand" "f")))]
1008 "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1009 "*
1010 {
1011 output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1012 if (TARGET_4300_MUL_FIX)
1013 output_asm_insn (\"nop\", operands);
1014 return \"\";
1015 }"
1016 [(set_attr "type" "fmul")
1017 (set_attr "mode" "SF")
1018 (set_attr "length" "2")]) ;; mul.s + nop
1019
1020 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1021 ;; a multiply is in progress, it may give an incorrect result. Avoid
1022 ;; this by keeping the mflo with the mult on the R4000.
1023
1024 (define_expand "mulsi3"
1025 [(set (match_operand:SI 0 "register_operand" "=l")
1026 (mult:SI (match_operand:SI 1 "register_operand" "d")
1027 (match_operand:SI 2 "register_operand" "d")))
1028 (clobber (match_scratch:SI 3 "=h"))
1029 (clobber (match_scratch:SI 4 "=a"))]
1030 ""
1031 "
1032 {
1033 if (GENERATE_MULT3)
1034 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1035 else if (TARGET_MAD)
1036 emit_insn (gen_mulsi3_r4650 (operands[0], operands[1], operands[2]));
1037 else if (mips_cpu != PROCESSOR_R4000)
1038 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1039 else
1040 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1041 DONE;
1042 }")
1043
1044 (define_insn "mulsi3_mult3"
1045 [(set (match_operand:SI 0 "register_operand" "=d")
1046 (mult:SI (match_operand:SI 1 "register_operand" "d")
1047 (match_operand:SI 2 "register_operand" "d")))
1048 (clobber (match_scratch:SI 3 "=h"))
1049 (clobber (match_scratch:SI 4 "=l"))
1050 (clobber (match_scratch:SI 5 "=a"))]
1051 "GENERATE_MULT3"
1052 "mult\\t%0,%1,%2"
1053 [(set_attr "type" "imul")
1054 (set_attr "mode" "SI")
1055 (set_attr "length" "1")])
1056
1057 (define_insn "mulsi3_internal"
1058 [(set (match_operand:SI 0 "register_operand" "=l")
1059 (mult:SI (match_operand:SI 1 "register_operand" "d")
1060 (match_operand:SI 2 "register_operand" "d")))
1061 (clobber (match_scratch:SI 3 "=h"))
1062 (clobber (match_scratch:SI 4 "=a"))]
1063 "mips_cpu != PROCESSOR_R4000"
1064 "mult\\t%1,%2"
1065 [(set_attr "type" "imul")
1066 (set_attr "mode" "SI")
1067 (set_attr "length" "1")])
1068
1069 (define_insn "mulsi3_r4000"
1070 [(set (match_operand:SI 0 "register_operand" "=d")
1071 (mult:SI (match_operand:SI 1 "register_operand" "d")
1072 (match_operand:SI 2 "register_operand" "d")))
1073 (clobber (match_scratch:SI 3 "=h"))
1074 (clobber (match_scratch:SI 4 "=l"))
1075 (clobber (match_scratch:SI 5 "=a"))]
1076 "mips_cpu == PROCESSOR_R4000"
1077 "*
1078 {
1079 rtx xoperands[10];
1080
1081 xoperands[0] = operands[0];
1082 xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1083
1084 output_asm_insn (\"mult\\t%1,%2\", operands);
1085 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1086 return \"\";
1087 }"
1088 [(set_attr "type" "imul")
1089 (set_attr "mode" "SI")
1090 (set_attr "length" "3")]) ;; mult + mflo + delay
1091
1092 (define_insn "mulsi3_r4650"
1093 [(set (match_operand:SI 0 "register_operand" "=d")
1094 (mult:SI (match_operand:SI 1 "register_operand" "d")
1095 (match_operand:SI 2 "register_operand" "d")))
1096 (clobber (match_scratch:SI 3 "=h"))
1097 (clobber (match_scratch:SI 4 "=l"))
1098 (clobber (match_scratch:SI 5 "=a"))]
1099 "TARGET_MAD"
1100 "mul\\t%0,%1,%2"
1101 [(set_attr "type" "imul")
1102 (set_attr "mode" "SI")
1103 (set_attr "length" "1")])
1104
1105 (define_expand "muldi3"
1106 [(set (match_operand:DI 0 "register_operand" "=l")
1107 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1108 (match_operand:DI 2 "register_operand" "d")))
1109 (clobber (match_scratch:DI 3 "=h"))
1110 (clobber (match_scratch:DI 4 "=a"))]
1111 "TARGET_64BIT"
1112 "
1113 {
1114 if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000)
1115 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1116 else
1117 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1118 DONE;
1119 }")
1120
1121 ;; Don't accept both operands using se_register_operand, because if
1122 ;; both operands are sign extended we would prefer to use mult in the
1123 ;; mulsidi3 pattern. Commutativity should permit either operand to be
1124 ;; sign extended.
1125
1126 (define_insn "muldi3_internal"
1127 [(set (match_operand:DI 0 "register_operand" "=l")
1128 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1129 (match_operand:DI 2 "register_operand" "d")))
1130 (clobber (match_scratch:DI 3 "=h"))
1131 (clobber (match_scratch:DI 4 "=a"))]
1132 "TARGET_64BIT && mips_cpu != PROCESSOR_R4000"
1133 "dmult\\t%1,%2"
1134 [(set_attr "type" "imul")
1135 (set_attr "mode" "DI")
1136 (set_attr "length" "1")])
1137
1138 (define_insn "muldi3_internal2"
1139 [(set (match_operand:DI 0 "register_operand" "=d")
1140 (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1141 (match_operand:DI 2 "register_operand" "d")))
1142 (clobber (match_scratch:DI 3 "=h"))
1143 (clobber (match_scratch:DI 4 "=l"))
1144 (clobber (match_scratch:DI 5 "=a"))]
1145 "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000)"
1146 "*
1147 {
1148 if (GENERATE_MULT3)
1149 output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1150 else
1151 {
1152 rtx xoperands[10];
1153
1154 xoperands[0] = operands[0];
1155 xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1156
1157 output_asm_insn (\"dmult\\t%1,%2\", operands);
1158 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1159 }
1160 return \"\";
1161 }"
1162 [(set_attr "type" "imul")
1163 (set_attr "mode" "DI")
1164 (set (attr "length")
1165 (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1166 (const_int 1)
1167 (const_int 3)))]) ;; mult + mflo + delay
1168
1169 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1170
1171 (define_expand "mulsidi3"
1172 [(set (match_operand:DI 0 "register_operand" "=x")
1173 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1174 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1175 ""
1176 "
1177 {
1178 if (TARGET_64BIT)
1179 emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
1180 else
1181 emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
1182 DONE;
1183 }")
1184
1185 (define_insn "mulsidi3_internal"
1186 [(set (match_operand:DI 0 "register_operand" "=x")
1187 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1188 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1189 (clobber (match_scratch:SI 3 "=a"))]
1190 "!TARGET_64BIT"
1191 "mult\\t%1,%2"
1192 [(set_attr "type" "imul")
1193 (set_attr "mode" "SI")
1194 (set_attr "length" "1")])
1195
1196 (define_insn "mulsidi3_64bit"
1197 [(set (match_operand:DI 0 "register_operand" "=a")
1198 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1199 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1200 (clobber (match_scratch:DI 3 "=l"))
1201 (clobber (match_scratch:DI 4 "=h"))]
1202 "TARGET_64BIT"
1203 "mult\\t%1,%2"
1204 [(set_attr "type" "imul")
1205 (set_attr "mode" "SI")
1206 (set_attr "length" "1")])
1207
1208 (define_insn "smulsi3_highpart"
1209 [(set (match_operand:SI 0 "register_operand" "=h")
1210 (truncate:SI
1211 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1212 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1213 (const_int 32))))
1214 (clobber (match_scratch:SI 3 "=l"))
1215 (clobber (match_scratch:SI 4 "=a"))]
1216 ""
1217 "mult\\t%1,%2"
1218 [(set_attr "type" "imul")
1219 (set_attr "mode" "SI")
1220 (set_attr "length" "1")])
1221
1222 (define_expand "umulsidi3"
1223 [(set (match_operand:DI 0 "register_operand" "=x")
1224 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1225 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1226 ""
1227 "
1228 {
1229 if (TARGET_64BIT)
1230 emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
1231 else
1232 emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
1233 DONE;
1234 }")
1235
1236 (define_insn "umulsidi3_internal"
1237 [(set (match_operand:DI 0 "register_operand" "=x")
1238 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1239 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1240 (clobber (match_scratch:SI 3 "=a"))]
1241 "!TARGET_64BIT"
1242 "multu\\t%1,%2"
1243 [(set_attr "type" "imul")
1244 (set_attr "mode" "SI")
1245 (set_attr "length" "1")])
1246
1247 (define_insn "umulsidi3_64bit"
1248 [(set (match_operand:DI 0 "register_operand" "=a")
1249 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1250 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1251 (clobber (match_scratch:DI 3 "=l"))
1252 (clobber (match_scratch:DI 4 "=h"))]
1253 "TARGET_64BIT"
1254 "multu\\t%1,%2"
1255 [(set_attr "type" "imul")
1256 (set_attr "mode" "SI")
1257 (set_attr "length" "1")])
1258
1259 (define_insn "umulsi3_highpart"
1260 [(set (match_operand:SI 0 "register_operand" "=h")
1261 (truncate:SI
1262 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1263 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1264 (const_int 32))))
1265 (clobber (match_scratch:SI 3 "=l"))
1266 (clobber (match_scratch:SI 4 "=a"))]
1267 ""
1268 "multu\\t%1,%2"
1269 [(set_attr "type" "imul")
1270 (set_attr "mode" "SI")
1271 (set_attr "length" "1")])
1272
1273 (define_insn "smuldi3_highpart"
1274 [(set (match_operand:DI 0 "register_operand" "=h")
1275 (truncate:DI
1276 (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1277 (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1278 (const_int 64))))
1279 (clobber (match_scratch:DI 3 "=l"))
1280 (clobber (match_scratch:DI 4 "=a"))]
1281 "TARGET_64BIT"
1282 "dmult\\t%1,%2"
1283 [(set_attr "type" "imul")
1284 (set_attr "mode" "DI")
1285 (set_attr "length" "1")])
1286
1287 (define_insn "umuldi3_highpart"
1288 [(set (match_operand:DI 0 "register_operand" "=h")
1289 (truncate:DI
1290 (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1291 (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1292 (const_int 64))))
1293 (clobber (match_scratch:DI 3 "=l"))
1294 (clobber (match_scratch:DI 4 "=a"))]
1295 "TARGET_64BIT"
1296 "dmultu\\t%1,%2"
1297 [(set_attr "type" "imul")
1298 (set_attr "mode" "DI")
1299 (set_attr "length" "1")])
1300
1301 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1302 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
1303
1304 (define_insn "madsi"
1305 [(set (match_operand:SI 0 "register_operand" "+l")
1306 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1307 (match_operand:SI 2 "register_operand" "d"))
1308 (match_dup 0)))
1309 (clobber (match_scratch:SI 3 "=h"))
1310 (clobber (match_scratch:SI 4 "=a"))]
1311 "TARGET_MAD || GENERATE_MADD"
1312 "*
1313 {
1314 if (TARGET_MAD)
1315 return \"mad\\t%1,%2\";
1316 else
1317 return \"madd\\t%1,%2\";
1318 }"
1319 [(set_attr "type" "imul")
1320 (set_attr "mode" "SI")
1321 (set_attr "length" "1")])
1322
1323 (define_insn "maddi"
1324 [(set (match_operand:DI 0 "register_operand" "+x")
1325 (plus:DI (mult:DI (sign_extend:DI
1326 (match_operand:SI 1 "register_operand" "d"))
1327 (sign_extend:DI
1328 (match_operand:SI 2 "register_operand" "d")))
1329 (match_dup 0)))
1330 (clobber (match_scratch:SI 3 "=a"))]
1331 "TARGET_MAD && ! TARGET_64BIT"
1332 "mad\\t%1,%2"
1333 [(set_attr "type" "imul")
1334 (set_attr "mode" "SI")
1335 (set_attr "length" "1")])
1336
1337 (define_insn "maddi_64bit"
1338 [(set (match_operand:DI 0 "register_operand" "+a")
1339 (plus:DI (mult:DI (sign_extend:DI
1340 (match_operand:SI 1 "register_operand" "d"))
1341 (sign_extend:DI
1342 (match_operand:SI 2 "register_operand" "d")))
1343 (match_dup 0)))
1344 (clobber (match_scratch:DI 3 "=l"))
1345 (clobber (match_scratch:DI 4 "=h"))]
1346 "TARGET_MAD && TARGET_64BIT"
1347 "mad\\t%1,%2"
1348 [(set_attr "type" "imul")
1349 (set_attr "mode" "SI")
1350 (set_attr "length" "1")])
1351
1352 (define_insn "umaddi"
1353 [(set (match_operand:DI 0 "register_operand" "+x")
1354 (plus:DI (mult:DI (zero_extend:DI
1355 (match_operand:SI 1 "register_operand" "d"))
1356 (zero_extend:DI
1357 (match_operand:SI 2 "register_operand" "d")))
1358 (match_dup 0)))
1359 (clobber (match_scratch:SI 3 "=a"))]
1360 "TARGET_MAD && ! TARGET_64BIT"
1361 "madu\\t%1,%2"
1362 [(set_attr "type" "imul")
1363 (set_attr "mode" "SI")
1364 (set_attr "length" "1")])
1365
1366 (define_insn "umaddi_64bit"
1367 [(set (match_operand:DI 0 "register_operand" "+a")
1368 (plus:DI (mult:DI (zero_extend:DI
1369 (match_operand:SI 1 "register_operand" "d"))
1370 (zero_extend:DI
1371 (match_operand:SI 2 "register_operand" "d")))
1372 (match_dup 0)))
1373 (clobber (match_scratch:DI 3 "=l"))
1374 (clobber (match_scratch:DI 4 "=h"))]
1375 "TARGET_MAD && TARGET_64BIT"
1376 "madu\\t%1,%2"
1377 [(set_attr "type" "imul")
1378 (set_attr "mode" "SI")
1379 (set_attr "length" "1")])
1380
1381 (define_insn "madd3"
1382 [(set (match_operand:SI 0 "register_operand" "=d")
1383 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1384 (match_operand:SI 2 "register_operand" "d"))
1385 (match_operand:SI 3 "register_operand" "l")))
1386 (clobber (match_scratch:SI 4 "=l"))
1387 (clobber (match_scratch:SI 5 "=h"))
1388 (clobber (match_scratch:SI 6 "=a"))]
1389 "GENERATE_MADD"
1390 "madd\\t%0,%1,%2"
1391 [(set_attr "type" "imul")
1392 (set_attr "mode" "SI")
1393 (set_attr "length" "1")])
1394
1395 ;; Floating point multiply accumulate instructions.
1396
1397 (define_insn ""
1398 [(set (match_operand:DF 0 "register_operand" "=f")
1399 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1400 (match_operand:DF 2 "register_operand" "f"))
1401 (match_operand:DF 3 "register_operand" "f")))]
1402 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1403 "madd.d\\t%0,%3,%1,%2"
1404 [(set_attr "type" "fmadd")
1405 (set_attr "mode" "DF")
1406 (set_attr "length" "1")])
1407
1408 (define_insn ""
1409 [(set (match_operand:SF 0 "register_operand" "=f")
1410 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1411 (match_operand:SF 2 "register_operand" "f"))
1412 (match_operand:SF 3 "register_operand" "f")))]
1413 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1414 "madd.s\\t%0,%3,%1,%2"
1415 [(set_attr "type" "fmadd")
1416 (set_attr "mode" "SF")
1417 (set_attr "length" "1")])
1418
1419 (define_insn ""
1420 [(set (match_operand:DF 0 "register_operand" "=f")
1421 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1422 (match_operand:DF 2 "register_operand" "f"))
1423 (match_operand:DF 3 "register_operand" "f")))]
1424 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1425 "msub.d\\t%0,%3,%1,%2"
1426 [(set_attr "type" "fmadd")
1427 (set_attr "mode" "DF")
1428 (set_attr "length" "1")])
1429
1430 (define_insn ""
1431 [(set (match_operand:SF 0 "register_operand" "=f")
1432 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1433 (match_operand:SF 2 "register_operand" "f"))
1434 (match_operand:SF 3 "register_operand" "f")))]
1435
1436 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1437 "msub.s\\t%0,%3,%1,%2"
1438 [(set_attr "type" "fmadd")
1439 (set_attr "mode" "SF")
1440 (set_attr "length" "1")])
1441
1442 (define_insn ""
1443 [(set (match_operand:DF 0 "register_operand" "=f")
1444 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1445 (match_operand:DF 2 "register_operand" "f"))
1446 (match_operand:DF 3 "register_operand" "f"))))]
1447 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1448 "nmadd.d\\t%0,%3,%1,%2"
1449 [(set_attr "type" "fmadd")
1450 (set_attr "mode" "DF")
1451 (set_attr "length" "1")])
1452
1453 (define_insn ""
1454 [(set (match_operand:SF 0 "register_operand" "=f")
1455 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1456 (match_operand:SF 2 "register_operand" "f"))
1457 (match_operand:SF 3 "register_operand" "f"))))]
1458 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1459 "nmadd.s\\t%0,%3,%1,%2"
1460 [(set_attr "type" "fmadd")
1461 (set_attr "mode" "SF")
1462 (set_attr "length" "1")])
1463
1464 (define_insn ""
1465 [(set (match_operand:DF 0 "register_operand" "=f")
1466 (minus:DF (match_operand:DF 1 "register_operand" "f")
1467 (mult:DF (match_operand:DF 2 "register_operand" "f")
1468 (match_operand:DF 3 "register_operand" "f"))))]
1469 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1470 "nmsub.d\\t%0,%1,%2,%3"
1471 [(set_attr "type" "fmadd")
1472 (set_attr "mode" "DF")
1473 (set_attr "length" "1")])
1474
1475 (define_insn ""
1476 [(set (match_operand:SF 0 "register_operand" "=f")
1477 (minus:SF (match_operand:SF 1 "register_operand" "f")
1478 (mult:SF (match_operand:SF 2 "register_operand" "f")
1479 (match_operand:SF 3 "register_operand" "f"))))]
1480 "mips_isa >= 4 && TARGET_HARD_FLOAT"
1481 "nmsub.s\\t%0,%1,%2,%3"
1482 [(set_attr "type" "fmadd")
1483 (set_attr "mode" "SF")
1484 (set_attr "length" "1")])
1485 \f
1486 ;;
1487 ;; ....................
1488 ;;
1489 ;; DIVISION and REMAINDER
1490 ;;
1491 ;; ....................
1492 ;;
1493
1494 (define_insn "divdf3"
1495 [(set (match_operand:DF 0 "register_operand" "=f")
1496 (div:DF (match_operand:DF 1 "register_operand" "f")
1497 (match_operand:DF 2 "register_operand" "f")))]
1498 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1499 "div.d\\t%0,%1,%2"
1500 [(set_attr "type" "fdiv")
1501 (set_attr "mode" "DF")
1502 (set_attr "length" "1")])
1503
1504 (define_insn "divsf3"
1505 [(set (match_operand:SF 0 "register_operand" "=f")
1506 (div:SF (match_operand:SF 1 "register_operand" "f")
1507 (match_operand:SF 2 "register_operand" "f")))]
1508 "TARGET_HARD_FLOAT"
1509 "div.s\\t%0,%1,%2"
1510 [(set_attr "type" "fdiv")
1511 (set_attr "mode" "SF")
1512 (set_attr "length" "1")])
1513
1514 (define_insn ""
1515 [(set (match_operand:DF 0 "register_operand" "=f")
1516 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1517 (match_operand:DF 2 "register_operand" "f")))]
1518 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
1519 "recip.d\\t%0,%2"
1520 [(set_attr "type" "fdiv")
1521 (set_attr "mode" "DF")
1522 (set_attr "length" "1")])
1523
1524 (define_insn ""
1525 [(set (match_operand:SF 0 "register_operand" "=f")
1526 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1527 (match_operand:SF 2 "register_operand" "f")))]
1528 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
1529 "recip.s\\t%0,%2"
1530 [(set_attr "type" "fdiv")
1531 (set_attr "mode" "SF")
1532 (set_attr "length" "1")])
1533
1534 ;; If optimizing, prefer the divmod functions over separate div and
1535 ;; mod functions, since this will allow using one instruction for both
1536 ;; the quotient and remainder. At present, the divmod is not moved out
1537 ;; of loops if it is constant within the loop, so allow -mdebugc to
1538 ;; use the old method of doing things.
1539
1540 ;; 64 is the multiply/divide hi register
1541 ;; 65 is the multiply/divide lo register
1542
1543 ;; ??? We can't accept constants here, because the MIPS assembler will replace
1544 ;; a divide by power of 2 with a shift, and then the remainder is no longer
1545 ;; available.
1546
1547 (define_insn "divmodsi4"
1548 [(set (match_operand:SI 0 "register_operand" "=d")
1549 (div:SI (match_operand:SI 1 "register_operand" "d")
1550 (match_operand:SI 2 "register_operand" "d")))
1551 (set (match_operand:SI 3 "register_operand" "=d")
1552 (mod:SI (match_dup 1)
1553 (match_dup 2)))
1554 (clobber (match_scratch:SI 4 "=l"))
1555 (clobber (match_scratch:SI 5 "=h"))
1556 (clobber (match_scratch:SI 6 "=a"))]
1557 "optimize"
1558 "*
1559 {
1560 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1561 return \"div\\t%0,%1,%2\";
1562
1563 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1564 return \"rem\\t%3,%1,%2\";
1565
1566 return \"div\\t%0,%1,%2\;mfhi\\t%3\";
1567 }"
1568 [(set_attr "type" "idiv")
1569 (set_attr "mode" "SI")
1570 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1571
1572 (define_insn "divmoddi4"
1573 [(set (match_operand:DI 0 "register_operand" "=d")
1574 (div:DI (match_operand:DI 1 "se_register_operand" "d")
1575 (match_operand:DI 2 "se_register_operand" "d")))
1576 (set (match_operand:DI 3 "register_operand" "=d")
1577 (mod:DI (match_dup 1)
1578 (match_dup 2)))
1579 (clobber (match_scratch:DI 4 "=l"))
1580 (clobber (match_scratch:DI 5 "=h"))
1581 (clobber (match_scratch:DI 6 "=a"))]
1582 "TARGET_64BIT && optimize"
1583 "*
1584 {
1585 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1586 return \"ddiv\\t%0,%1,%2\";
1587
1588 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1589 return \"drem\\t%3,%1,%2\";
1590
1591 return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
1592 }"
1593 [(set_attr "type" "idiv")
1594 (set_attr "mode" "DI")
1595 (set_attr "length" "15")]) ;; various tests for dividing by 0 and such
1596
1597 (define_insn "udivmodsi4"
1598 [(set (match_operand:SI 0 "register_operand" "=d")
1599 (udiv:SI (match_operand:SI 1 "register_operand" "d")
1600 (match_operand:SI 2 "register_operand" "d")))
1601 (set (match_operand:SI 3 "register_operand" "=d")
1602 (umod:SI (match_dup 1)
1603 (match_dup 2)))
1604 (clobber (match_scratch:SI 4 "=l"))
1605 (clobber (match_scratch:SI 5 "=h"))
1606 (clobber (match_scratch:SI 6 "=a"))]
1607 "optimize"
1608 "*
1609 {
1610 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1611 return \"divu\\t%0,%1,%2\";
1612
1613 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1614 return \"remu\\t%3,%1,%2\";
1615
1616 return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
1617 }"
1618 [(set_attr "type" "idiv")
1619 (set_attr "mode" "SI")
1620 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
1621
1622 (define_insn "udivmoddi4"
1623 [(set (match_operand:DI 0 "register_operand" "=d")
1624 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
1625 (match_operand:DI 2 "se_register_operand" "d")))
1626 (set (match_operand:DI 3 "register_operand" "=d")
1627 (umod:DI (match_dup 1)
1628 (match_dup 2)))
1629 (clobber (match_scratch:DI 4 "=l"))
1630 (clobber (match_scratch:DI 5 "=h"))
1631 (clobber (match_scratch:DI 6 "=a"))]
1632 "TARGET_64BIT && optimize"
1633 "*
1634 {
1635 if (find_reg_note (insn, REG_UNUSED, operands[3]))
1636 return \"ddivu\\t%0,%1,%2\";
1637
1638 if (find_reg_note (insn, REG_UNUSED, operands[0]))
1639 return \"dremu\\t%3,%1,%2\";
1640
1641 return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
1642 }"
1643 [(set_attr "type" "idiv")
1644 (set_attr "mode" "DI")
1645 (set_attr "length" "8")]) ;; various tests for dividing by 0 and such
1646
1647 (define_insn "divsi3"
1648 [(set (match_operand:SI 0 "register_operand" "=d")
1649 (div:SI (match_operand:SI 1 "register_operand" "d")
1650 (match_operand:SI 2 "nonmemory_operand" "di")))
1651 (clobber (match_scratch:SI 3 "=l"))
1652 (clobber (match_scratch:SI 4 "=h"))
1653 (clobber (match_scratch:SI 6 "=a"))]
1654 "!optimize"
1655 "div\\t%0,%1,%2"
1656 [(set_attr "type" "idiv")
1657 (set_attr "mode" "SI")
1658 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
1659
1660 (define_insn "divdi3"
1661 [(set (match_operand:DI 0 "register_operand" "=d")
1662 (div:DI (match_operand:DI 1 "se_register_operand" "d")
1663 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1664 (clobber (match_scratch:DI 3 "=l"))
1665 (clobber (match_scratch:DI 4 "=h"))
1666 (clobber (match_scratch:DI 6 "=a"))]
1667 "TARGET_64BIT && !optimize"
1668 "ddiv\\t%0,%1,%2"
1669 [(set_attr "type" "idiv")
1670 (set_attr "mode" "DI")
1671 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1672
1673 (define_insn "modsi3"
1674 [(set (match_operand:SI 0 "register_operand" "=d")
1675 (mod:SI (match_operand:SI 1 "register_operand" "d")
1676 (match_operand:SI 2 "nonmemory_operand" "di")))
1677 (clobber (match_scratch:SI 3 "=l"))
1678 (clobber (match_scratch:SI 4 "=h"))
1679 (clobber (match_scratch:SI 6 "=a"))]
1680 "!optimize"
1681 "rem\\t%0,%1,%2"
1682 [(set_attr "type" "idiv")
1683 (set_attr "mode" "SI")
1684 (set_attr "length" "13")]) ;; various tests for dividing by 0 and such
1685
1686 (define_insn "moddi3"
1687 [(set (match_operand:DI 0 "register_operand" "=d")
1688 (mod:DI (match_operand:DI 1 "se_register_operand" "d")
1689 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1690 (clobber (match_scratch:DI 3 "=l"))
1691 (clobber (match_scratch:DI 4 "=h"))
1692 (clobber (match_scratch:DI 6 "=a"))]
1693 "TARGET_64BIT && !optimize"
1694 "drem\\t%0,%1,%2"
1695 [(set_attr "type" "idiv")
1696 (set_attr "mode" "DI")
1697 (set_attr "length" "14")]) ;; various tests for dividing by 0 and such
1698
1699 (define_insn "udivsi3"
1700 [(set (match_operand:SI 0 "register_operand" "=d")
1701 (udiv:SI (match_operand:SI 1 "register_operand" "d")
1702 (match_operand:SI 2 "nonmemory_operand" "di")))
1703 (clobber (match_scratch:SI 3 "=l"))
1704 (clobber (match_scratch:SI 4 "=h"))
1705 (clobber (match_scratch:SI 6 "=a"))]
1706 "!optimize"
1707 "divu\\t%0,%1,%2"
1708 [(set_attr "type" "idiv")
1709 (set_attr "mode" "SI")
1710 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1711
1712 (define_insn "udivdi3"
1713 [(set (match_operand:DI 0 "register_operand" "=d")
1714 (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
1715 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1716 (clobber (match_scratch:DI 3 "=l"))
1717 (clobber (match_scratch:DI 4 "=h"))
1718 (clobber (match_scratch:DI 6 "=a"))]
1719 "TARGET_64BIT && !optimize"
1720 "ddivu\\t%0,%1,%2"
1721 [(set_attr "type" "idiv")
1722 (set_attr "mode" "DI")
1723 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1724
1725 (define_insn "umodsi3"
1726 [(set (match_operand:SI 0 "register_operand" "=d")
1727 (umod:SI (match_operand:SI 1 "register_operand" "d")
1728 (match_operand:SI 2 "nonmemory_operand" "di")))
1729 (clobber (match_scratch:SI 3 "=l"))
1730 (clobber (match_scratch:SI 4 "=h"))
1731 (clobber (match_scratch:SI 6 "=a"))]
1732 "!optimize"
1733 "remu\\t%0,%1,%2"
1734 [(set_attr "type" "idiv")
1735 (set_attr "mode" "SI")
1736 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1737
1738 (define_insn "umoddi3"
1739 [(set (match_operand:DI 0 "register_operand" "=d")
1740 (umod:DI (match_operand:DI 1 "se_register_operand" "d")
1741 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1742 (clobber (match_scratch:DI 3 "=l"))
1743 (clobber (match_scratch:DI 4 "=h"))
1744 (clobber (match_scratch:DI 6 "=a"))]
1745 "TARGET_64BIT && !optimize"
1746 "dremu\\t%0,%1,%2"
1747 [(set_attr "type" "idiv")
1748 (set_attr "mode" "DI")
1749 (set_attr "length" "7")]) ;; various tests for dividing by 0 and such
1750
1751 \f
1752 ;;
1753 ;; ....................
1754 ;;
1755 ;; SQUARE ROOT
1756 ;;
1757 ;; ....................
1758
1759 (define_insn "sqrtdf2"
1760 [(set (match_operand:DF 0 "register_operand" "=f")
1761 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1762 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1763 "sqrt.d\\t%0,%1"
1764 [(set_attr "type" "fsqrt")
1765 (set_attr "mode" "DF")
1766 (set_attr "length" "1")])
1767
1768 (define_insn "sqrtsf2"
1769 [(set (match_operand:SF 0 "register_operand" "=f")
1770 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1771 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1772 "sqrt.s\\t%0,%1"
1773 [(set_attr "type" "fsqrt")
1774 (set_attr "mode" "SF")
1775 (set_attr "length" "1")])
1776
1777 (define_insn ""
1778 [(set (match_operand:DF 0 "register_operand" "=f")
1779 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1780 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1781 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
1782 "rsqrt.d\\t%0,%2"
1783 [(set_attr "type" "fsqrt")
1784 (set_attr "mode" "DF")
1785 (set_attr "length" "1")])
1786
1787 (define_insn ""
1788 [(set (match_operand:SF 0 "register_operand" "=f")
1789 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1790 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1791 "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
1792 "rsqrt.s\\t%0,%2"
1793 [(set_attr "type" "fsqrt")
1794 (set_attr "mode" "SF")
1795 (set_attr "length" "1")])
1796
1797 \f
1798 ;;
1799 ;; ....................
1800 ;;
1801 ;; ABSOLUTE VALUE
1802 ;;
1803 ;; ....................
1804
1805 ;; Do not use the integer abs macro instruction, since that signals an
1806 ;; exception on -2147483648 (sigh).
1807
1808 (define_insn "abssi2"
1809 [(set (match_operand:SI 0 "register_operand" "=d")
1810 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1811 ""
1812 "*
1813 {
1814 dslots_jump_total++;
1815 dslots_jump_filled++;
1816 operands[2] = const0_rtx;
1817
1818 if (REGNO (operands[0]) == REGNO (operands[1]))
1819 {
1820 if (GENERATE_BRANCHLIKELY)
1821 return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1822 else
1823 return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
1824 }
1825 else
1826 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1827 }"
1828 [(set_attr "type" "multi")
1829 (set_attr "mode" "SI")
1830 (set_attr "length" "3")])
1831
1832 (define_insn "absdi2"
1833 [(set (match_operand:DI 0 "register_operand" "=d")
1834 (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
1835 "TARGET_64BIT"
1836 "*
1837 {
1838 dslots_jump_total++;
1839 dslots_jump_filled++;
1840 operands[2] = const0_rtx;
1841
1842 if (REGNO (operands[0]) == REGNO (operands[1]))
1843 return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1844 else
1845 return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1846 }"
1847 [(set_attr "type" "multi")
1848 (set_attr "mode" "DI")
1849 (set_attr "length" "3")])
1850
1851 (define_insn "absdf2"
1852 [(set (match_operand:DF 0 "register_operand" "=f")
1853 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1854 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1855 "abs.d\\t%0,%1"
1856 [(set_attr "type" "fabs")
1857 (set_attr "mode" "DF")
1858 (set_attr "length" "1")])
1859
1860 (define_insn "abssf2"
1861 [(set (match_operand:SF 0 "register_operand" "=f")
1862 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1863 "TARGET_HARD_FLOAT"
1864 "abs.s\\t%0,%1"
1865 [(set_attr "type" "fabs")
1866 (set_attr "mode" "SF")
1867 (set_attr "length" "1")])
1868
1869 \f
1870 ;;
1871 ;; ....................
1872 ;;
1873 ;; FIND FIRST BIT INSTRUCTION
1874 ;;
1875 ;; ....................
1876 ;;
1877
1878 (define_insn "ffssi2"
1879 [(set (match_operand:SI 0 "register_operand" "=&d")
1880 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
1881 (clobber (match_scratch:SI 2 "=&d"))
1882 (clobber (match_scratch:SI 3 "=&d"))]
1883 ""
1884 "*
1885 {
1886 dslots_jump_total += 2;
1887 dslots_jump_filled += 2;
1888 operands[4] = const0_rtx;
1889
1890 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1891 return \"%(\\
1892 move\\t%0,%z4\\n\\
1893 \\tbeq\\t%1,%z4,2f\\n\\
1894 1:\\tand\\t%2,%1,0x0001\\n\\
1895 \\taddu\\t%0,%0,1\\n\\
1896 \\tbeq\\t%2,%z4,1b\\n\\
1897 \\tsrl\\t%1,%1,1\\n\\
1898 2:%)\";
1899
1900 return \"%(\\
1901 move\\t%0,%z4\\n\\
1902 \\tmove\\t%3,%1\\n\\
1903 \\tbeq\\t%3,%z4,2f\\n\\
1904 1:\\tand\\t%2,%3,0x0001\\n\\
1905 \\taddu\\t%0,%0,1\\n\\
1906 \\tbeq\\t%2,%z4,1b\\n\\
1907 \\tsrl\\t%3,%3,1\\n\\
1908 2:%)\";
1909 }"
1910 [(set_attr "type" "multi")
1911 (set_attr "mode" "SI")
1912 (set_attr "length" "6")])
1913
1914 (define_insn "ffsdi2"
1915 [(set (match_operand:DI 0 "register_operand" "=&d")
1916 (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
1917 (clobber (match_scratch:DI 2 "=&d"))
1918 (clobber (match_scratch:DI 3 "=&d"))]
1919 "TARGET_64BIT"
1920 "*
1921 {
1922 dslots_jump_total += 2;
1923 dslots_jump_filled += 2;
1924 operands[4] = const0_rtx;
1925
1926 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1927 return \"%(\\
1928 move\\t%0,%z4\\n\\
1929 \\tbeq\\t%1,%z4,2f\\n\\
1930 1:\\tand\\t%2,%1,0x0001\\n\\
1931 \\tdaddu\\t%0,%0,1\\n\\
1932 \\tbeq\\t%2,%z4,1b\\n\\
1933 \\tdsrl\\t%1,%1,1\\n\\
1934 2:%)\";
1935
1936 return \"%(\\
1937 move\\t%0,%z4\\n\\
1938 \\tmove\\t%3,%1\\n\\
1939 \\tbeq\\t%3,%z4,2f\\n\\
1940 1:\\tand\\t%2,%3,0x0001\\n\\
1941 \\tdaddu\\t%0,%0,1\\n\\
1942 \\tbeq\\t%2,%z4,1b\\n\\
1943 \\tdsrl\\t%3,%3,1\\n\\
1944 2:%)\";
1945 }"
1946 [(set_attr "type" "multi")
1947 (set_attr "mode" "DI")
1948 (set_attr "length" "6")])
1949
1950 \f
1951 ;;
1952 ;; ....................
1953 ;;
1954 ;; NEGATION and ONE'S COMPLEMENT
1955 ;;
1956 ;; ....................
1957
1958 (define_insn "negsi2"
1959 [(set (match_operand:SI 0 "register_operand" "=d")
1960 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1961 ""
1962 "*
1963 {
1964 operands[2] = const0_rtx;
1965 return \"subu\\t%0,%z2,%1\";
1966 }"
1967 [(set_attr "type" "arith")
1968 (set_attr "mode" "SI")
1969 (set_attr "length" "1")])
1970
1971 (define_expand "negdi2"
1972 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1973 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
1974 (clobber (match_dup 2))])]
1975 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1976 "
1977 {
1978 if (TARGET_64BIT)
1979 {
1980 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
1981 DONE;
1982 }
1983
1984 operands[2] = gen_reg_rtx (SImode);
1985 }")
1986
1987 (define_insn "negdi2_internal"
1988 [(set (match_operand:DI 0 "register_operand" "=d")
1989 (neg:DI (match_operand:DI 1 "register_operand" "d")))
1990 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1991 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE"
1992 "*
1993 {
1994 operands[3] = const0_rtx;
1995 return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1996 }"
1997 [(set_attr "type" "darith")
1998 (set_attr "mode" "DI")
1999 (set_attr "length" "4")])
2000
2001 (define_insn "negdi2_internal_2"
2002 [(set (match_operand:DI 0 "register_operand" "=d")
2003 (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
2004 "TARGET_64BIT"
2005 "*
2006 {
2007 operands[2] = const0_rtx;
2008 return \"dsubu\\t%0,%z2,%1\";
2009 }"
2010 [(set_attr "type" "arith")
2011 (set_attr "mode" "DI")
2012 (set_attr "length" "1")])
2013
2014 (define_insn "negdf2"
2015 [(set (match_operand:DF 0 "register_operand" "=f")
2016 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2017 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2018 "neg.d\\t%0,%1"
2019 [(set_attr "type" "fneg")
2020 (set_attr "mode" "DF")
2021 (set_attr "length" "1")])
2022
2023 (define_insn "negsf2"
2024 [(set (match_operand:SF 0 "register_operand" "=f")
2025 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2026 "TARGET_HARD_FLOAT"
2027 "neg.s\\t%0,%1"
2028 [(set_attr "type" "fneg")
2029 (set_attr "mode" "SF")
2030 (set_attr "length" "1")])
2031
2032 (define_insn "one_cmplsi2"
2033 [(set (match_operand:SI 0 "register_operand" "=d")
2034 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2035 ""
2036 "*
2037 {
2038 operands[2] = const0_rtx;
2039 return \"nor\\t%0,%z2,%1\";
2040 }"
2041 [(set_attr "type" "arith")
2042 (set_attr "mode" "SI")
2043 (set_attr "length" "1")])
2044
2045 (define_insn "one_cmpldi2"
2046 [(set (match_operand:DI 0 "register_operand" "=d")
2047 (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
2048 ""
2049 "*
2050 {
2051 operands[2] = const0_rtx;
2052 if (TARGET_64BIT)
2053 return \"nor\\t%0,%z2,%1\";
2054 return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
2055 }"
2056 [(set_attr "type" "darith")
2057 (set_attr "mode" "DI")
2058 (set (attr "length")
2059 (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2060 (const_int 1)
2061 (const_int 2)))])
2062
2063 (define_split
2064 [(set (match_operand:DI 0 "register_operand" "")
2065 (not:DI (match_operand:DI 1 "register_operand" "")))]
2066 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2067 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2068 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2069
2070 [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
2071 (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
2072 "")
2073
2074 \f
2075 ;;
2076 ;; ....................
2077 ;;
2078 ;; LOGICAL
2079 ;;
2080 ;; ....................
2081 ;;
2082
2083 (define_insn "andsi3"
2084 [(set (match_operand:SI 0 "register_operand" "=d,d")
2085 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2086 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2087 ""
2088 "@
2089 and\\t%0,%1,%2
2090 andi\\t%0,%1,%x2"
2091 [(set_attr "type" "arith")
2092 (set_attr "mode" "SI")
2093 (set_attr "length" "1")])
2094
2095 (define_insn "anddi3"
2096 [(set (match_operand:DI 0 "register_operand" "=d")
2097 (and:DI (match_operand:DI 1 "se_register_operand" "d")
2098 (match_operand:DI 2 "se_register_operand" "d")))]
2099 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2100 "*
2101 {
2102 if (TARGET_64BIT)
2103 return \"and\\t%0,%1,%2\";
2104 return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
2105 }"
2106 [(set_attr "type" "darith")
2107 (set_attr "mode" "DI")
2108 (set (attr "length")
2109 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2110 (const_int 1)
2111 (const_int 2)))])
2112
2113 (define_split
2114 [(set (match_operand:DI 0 "register_operand" "")
2115 (and:DI (match_operand:DI 1 "register_operand" "")
2116 (match_operand:DI 2 "register_operand" "")))]
2117 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2118 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2119 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2120 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2121
2122 [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2123 (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2124 "")
2125
2126 (define_insn "anddi3_internal1"
2127 [(set (match_operand:DI 0 "register_operand" "=d,d")
2128 (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
2129 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2130 "TARGET_64BIT"
2131 "@
2132 and\\t%0,%1,%2
2133 andi\\t%0,%1,%x2"
2134 [(set_attr "type" "arith")
2135 (set_attr "mode" "DI")
2136 (set_attr "length" "1")])
2137
2138 (define_insn "iorsi3"
2139 [(set (match_operand:SI 0 "register_operand" "=d,d")
2140 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2141 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2142 ""
2143 "@
2144 or\\t%0,%1,%2
2145 ori\\t%0,%1,%x2"
2146 [(set_attr "type" "arith")
2147 (set_attr "mode" "SI")
2148 (set_attr "length" "1")])
2149
2150 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
2151 ;;; TARGET_64BIT
2152
2153 (define_insn "iordi3"
2154 [(set (match_operand:DI 0 "register_operand" "=d")
2155 (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2156 (match_operand:DI 2 "se_register_operand" "d")))]
2157 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2158 "*
2159 {
2160 if (TARGET_64BIT)
2161 return \"or\\t%0,%1,%2\";
2162 return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
2163 }"
2164 [(set_attr "type" "darith")
2165 (set_attr "mode" "DI")
2166 (set (attr "length")
2167 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2168 (const_int 1)
2169 (const_int 2)))])
2170
2171 (define_split
2172 [(set (match_operand:DI 0 "register_operand" "")
2173 (ior:DI (match_operand:DI 1 "register_operand" "")
2174 (match_operand:DI 2 "register_operand" "")))]
2175 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2176 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2177 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2178 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2179
2180 [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2181 (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2182 "")
2183
2184 (define_insn "xorsi3"
2185 [(set (match_operand:SI 0 "register_operand" "=d,d")
2186 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2187 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2188 ""
2189 "@
2190 xor\\t%0,%1,%2
2191 xori\\t%0,%1,%x2"
2192 [(set_attr "type" "arith")
2193 (set_attr "mode" "SI")
2194 (set_attr "length" "1")])
2195
2196 ;; ??? If delete the 32-bit long long patterns, then could merge this with
2197 ;; the following xordi3_internal pattern.
2198 (define_insn "xordi3"
2199 [(set (match_operand:DI 0 "register_operand" "=d")
2200 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
2201 (match_operand:DI 2 "se_register_operand" "d")))]
2202 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2203 "*
2204 {
2205 if (TARGET_64BIT)
2206 return \"xor\\t%0,%1,%2\";
2207 return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
2208 }"
2209 [(set_attr "type" "darith")
2210 (set_attr "mode" "DI")
2211 (set (attr "length")
2212 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2213 (const_int 1)
2214 (const_int 2)))])
2215
2216 (define_split
2217 [(set (match_operand:DI 0 "register_operand" "")
2218 (xor:DI (match_operand:DI 1 "register_operand" "")
2219 (match_operand:DI 2 "register_operand" "")))]
2220 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2221 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2222 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2223 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2224
2225 [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2226 (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2227 "")
2228
2229 (define_insn "xordi3_immed"
2230 [(set (match_operand:DI 0 "register_operand" "d")
2231 (xor:DI (match_operand:DI 1 "se_register_operand" "d")
2232 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
2233 "TARGET_64BIT"
2234 "xori\\t%0,%1,%x2"
2235 [(set_attr "type" "arith")
2236 (set_attr "mode" "DI")
2237 (set_attr "length" "1")])
2238
2239 (define_insn "*norsi3"
2240 [(set (match_operand:SI 0 "register_operand" "=d")
2241 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2242 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2243 ""
2244 "nor\\t%0,%z1,%z2"
2245 [(set_attr "type" "arith")
2246 (set_attr "mode" "SI")
2247 (set_attr "length" "1")])
2248
2249 (define_insn "*nordi3"
2250 [(set (match_operand:DI 0 "register_operand" "=d")
2251 (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
2252 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
2253 ""
2254 "*
2255 {
2256 if (TARGET_64BIT)
2257 return \"nor\\t%0,%z1,%z2\";
2258 return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
2259 }"
2260 [(set_attr "type" "darith")
2261 (set_attr "mode" "DI")
2262 (set (attr "length")
2263 (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2264 (const_int 1)
2265 (const_int 2)))])
2266
2267 (define_split
2268 [(set (match_operand:DI 0 "register_operand" "")
2269 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
2270 (not:DI (match_operand:DI 2 "register_operand" ""))))]
2271 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2272 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2273 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2274 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2275
2276 [(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))))
2277 (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))))]
2278 "")
2279 \f
2280 ;;
2281 ;; ....................
2282 ;;
2283 ;; TRUNCATION
2284 ;;
2285 ;; ....................
2286
2287 (define_insn "truncdfsf2"
2288 [(set (match_operand:SF 0 "register_operand" "=f")
2289 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2290 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2291 "cvt.s.d\\t%0,%1"
2292 [(set_attr "type" "fcvt")
2293 (set_attr "mode" "SF")
2294 (set_attr "length" "1")])
2295
2296 (define_insn "truncdisi2"
2297 [(set (match_operand:SI 0 "register_operand" "=d")
2298 (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
2299 "TARGET_64BIT"
2300 "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
2301 [(set_attr "type" "darith")
2302 (set_attr "mode" "SI")
2303 (set_attr "length" "2")])
2304
2305 (define_insn "truncdihi2"
2306 [(set (match_operand:HI 0 "register_operand" "=d")
2307 (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
2308 "TARGET_64BIT"
2309 "andi\\t%0,%1,0xffff"
2310 [(set_attr "type" "darith")
2311 (set_attr "mode" "HI")
2312 (set_attr "length" "1")])
2313
2314 (define_insn "truncdiqi2"
2315 [(set (match_operand:QI 0 "register_operand" "=d")
2316 (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
2317 "TARGET_64BIT"
2318 "andi\\t%0,%1,0x00ff"
2319 [(set_attr "type" "darith")
2320 (set_attr "mode" "QI")
2321 (set_attr "length" "1")])
2322
2323 ;; Combiner patterns to optimize shift/truncate combinations.
2324 (define_insn ""
2325 [(set (match_operand:SI 0 "register_operand" "=d")
2326 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
2327 (match_operand:DI 2 "small_int" "I"))))]
2328 "TARGET_64BIT"
2329 "*
2330 {
2331 int shift_amt = INTVAL (operands[2]) & 0x3f;
2332
2333 if (shift_amt < 32)
2334 {
2335 operands[2] = GEN_INT (32 - shift_amt);
2336 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2337 }
2338 else
2339 {
2340 operands[2] = GEN_INT (shift_amt);
2341 return \"dsra\\t%0,%1,%2\";
2342 }
2343 }"
2344 [(set_attr "type" "darith")
2345 (set_attr "mode" "SI")
2346 (set_attr "length" "2")])
2347
2348 (define_insn ""
2349 [(set (match_operand:SI 0 "register_operand" "=d")
2350 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
2351 (match_operand:DI 2 "small_int" "I"))))]
2352 "TARGET_64BIT"
2353 "*
2354 {
2355 int shift_amt = INTVAL (operands[2]) & 0x3f;
2356
2357 if (shift_amt < 32)
2358 {
2359 operands[2] = GEN_INT (32 - shift_amt);
2360 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2361 }
2362 else if (shift_amt == 32)
2363 return \"dsra\\t%0,%1,32\";
2364 else
2365 {
2366 operands[2] = GEN_INT (shift_amt);
2367 return \"dsrl\\t%0,%1,%2\";
2368 }
2369 }"
2370 [(set_attr "type" "darith")
2371 (set_attr "mode" "SI")
2372 (set_attr "length" "2")])
2373
2374 (define_insn ""
2375 [(set (match_operand:SI 0 "register_operand" "=d")
2376 (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
2377 (match_operand:DI 2 "small_int" "I"))))]
2378 "TARGET_64BIT"
2379 "*
2380 {
2381 int shift_amt = INTVAL (operands[2]) & 0x3f;
2382
2383 if (shift_amt < 32)
2384 {
2385 operands[2] = GEN_INT (32 + shift_amt);
2386 return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2387 }
2388 else
2389 return \"move\\t%0,%.\";
2390 }"
2391 [(set_attr "type" "darith")
2392 (set_attr "mode" "SI")
2393 (set_attr "length" "2")])
2394
2395 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2396
2397 (define_insn ""
2398 [(set (match_operand:SI 0 "register_operand" "=d")
2399 (zero_extend:SI (truncate:HI
2400 (match_operand:DI 1 "se_register_operand" "d"))))]
2401 "TARGET_64BIT"
2402 "andi\\t%0,%1,0xffff"
2403 [(set_attr "type" "darith")
2404 (set_attr "mode" "SI")
2405 (set_attr "length" "1")])
2406
2407 (define_insn ""
2408 [(set (match_operand:SI 0 "register_operand" "=d")
2409 (zero_extend:SI (truncate:QI
2410 (match_operand:DI 1 "se_register_operand" "d"))))]
2411 "TARGET_64BIT"
2412 "andi\\t%0,%1,0xff"
2413 [(set_attr "type" "darith")
2414 (set_attr "mode" "SI")
2415 (set_attr "length" "1")])
2416
2417 (define_insn ""
2418 [(set (match_operand:HI 0 "register_operand" "=d")
2419 (zero_extend:HI (truncate:QI
2420 (match_operand:DI 1 "se_register_operand" "d"))))]
2421 "TARGET_64BIT"
2422 "andi\\t%0,%1,0xff"
2423 [(set_attr "type" "darith")
2424 (set_attr "mode" "HI")
2425 (set_attr "length" "1")])
2426 \f
2427 ;;
2428 ;; ....................
2429 ;;
2430 ;; ZERO EXTENSION
2431 ;;
2432 ;; ....................
2433
2434 ;; Extension insns.
2435 ;; Those for integer source operand are ordered widest source type first.
2436
2437 (define_expand "zero_extendsidi2"
2438 [(set (match_operand:DI 0 "register_operand" "")
2439 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2440 "TARGET_64BIT"
2441 "
2442 {
2443 if (optimize && GET_CODE (operands[1]) == MEM)
2444 operands[1] = force_not_mem (operands[1]);
2445
2446 if (GET_CODE (operands[1]) != MEM)
2447 {
2448 rtx op1 = gen_lowpart (DImode, operands[1]);
2449 rtx temp = gen_reg_rtx (DImode);
2450 rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
2451
2452 emit_insn (gen_ashldi3 (temp, op1, shift));
2453 emit_insn (gen_lshrdi3 (operands[0], temp, shift));
2454 DONE;
2455 }
2456 }")
2457
2458 (define_insn "zero_extendsidi2_internal"
2459 [(set (match_operand:DI 0 "register_operand" "=d,d")
2460 (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
2461 "TARGET_64BIT"
2462 "* return mips_move_1word (operands, insn, TRUE);"
2463 [(set_attr "type" "load")
2464 (set_attr "mode" "DI")
2465 (set_attr "length" "1,2")])
2466
2467 (define_insn "zero_extendhisi2"
2468 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2469 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2470 ""
2471 "*
2472 {
2473 if (which_alternative == 0)
2474 return \"andi\\t%0,%1,0xffff\";
2475 else
2476 return mips_move_1word (operands, insn, TRUE);
2477 }"
2478 [(set_attr "type" "arith,load,load")
2479 (set_attr "mode" "SI")
2480 (set_attr "length" "1,1,2")])
2481
2482 (define_insn "zero_extendhidi2"
2483 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2484 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2485 "TARGET_64BIT"
2486 "*
2487 {
2488 if (which_alternative == 0)
2489 return \"andi\\t%0,%1,0xffff\";
2490 else
2491 return mips_move_1word (operands, insn, TRUE);
2492 }"
2493 [(set_attr "type" "arith,load,load")
2494 (set_attr "mode" "DI")
2495 (set_attr "length" "1,1,2")])
2496
2497 (define_insn "zero_extendqihi2"
2498 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2499 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2500 ""
2501 "*
2502 {
2503 if (which_alternative == 0)
2504 return \"andi\\t%0,%1,0x00ff\";
2505 else
2506 return mips_move_1word (operands, insn, TRUE);
2507 }"
2508 [(set_attr "type" "arith,load,load")
2509 (set_attr "mode" "HI")
2510 (set_attr "length" "1,1,2")])
2511
2512 (define_insn "zero_extendqisi2"
2513 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2514 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2515 ""
2516 "*
2517 {
2518 if (which_alternative == 0)
2519 return \"andi\\t%0,%1,0x00ff\";
2520 else
2521 return mips_move_1word (operands, insn, TRUE);
2522 }"
2523 [(set_attr "type" "arith,load,load")
2524 (set_attr "mode" "SI")
2525 (set_attr "length" "1,1,2")])
2526
2527 (define_insn "zero_extendqidi2"
2528 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2529 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2530 "TARGET_64BIT"
2531 "*
2532 {
2533 if (which_alternative == 0)
2534 return \"andi\\t%0,%1,0x00ff\";
2535 else
2536 return mips_move_1word (operands, insn, TRUE);
2537 }"
2538 [(set_attr "type" "arith,load,load")
2539 (set_attr "mode" "DI")
2540 (set_attr "length" "1,1,2")])
2541
2542 ;; These can be created when a paradoxical subreg operand with an implicit
2543 ;; sign_extend operator is reloaded. Because of the subreg, this is really
2544 ;; a zero extend.
2545 ;; ??? It might be possible to eliminate the need for these patterns by adding
2546 ;; more support to reload for implicit sign_extend operators.
2547 (define_insn "*paradoxical_extendhidi2"
2548 [(set (match_operand:DI 0 "register_operand" "=d,d")
2549 (sign_extend:DI
2550 (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
2551 "TARGET_64BIT"
2552 "*
2553 {
2554 return mips_move_1word (operands, insn, TRUE);
2555 }"
2556 [(set_attr "type" "load,load")
2557 (set_attr "mode" "DI")
2558 (set_attr "length" "1,2")])
2559
2560 (define_insn "*paradoxical_extendqidi2"
2561 [(set (match_operand:DI 0 "register_operand" "=d,d")
2562 (sign_extend:DI
2563 (subreg:SI (match_operand:QI 1 "memory_operand" "R,m") 0)))]
2564 "TARGET_64BIT"
2565 "*
2566 {
2567 return mips_move_1word (operands, insn, TRUE);
2568 }"
2569 [(set_attr "type" "load,load")
2570 (set_attr "mode" "DI")
2571 (set_attr "length" "1,2")])
2572 \f
2573 ;;
2574 ;; ....................
2575 ;;
2576 ;; SIGN EXTENSION
2577 ;;
2578 ;; ....................
2579
2580 ;; Extension insns.
2581 ;; Those for integer source operand are ordered widest source type first.
2582
2583 ;; In 64 bit mode, 32 bit values in general registers are always
2584 ;; correctly sign extended. That means that if the target is a
2585 ;; general register, we can sign extend from SImode to DImode just by
2586 ;; doing a move.
2587
2588 (define_insn "extendsidi2"
2589 [(set (match_operand:DI 0 "register_operand" "=d,*d,d,d")
2590 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,*x,R,m")))]
2591 "TARGET_64BIT"
2592 "* return mips_move_1word (operands, insn, FALSE);"
2593 [(set_attr "type" "move,hilo,load,load")
2594 (set_attr "mode" "DI")
2595 (set_attr "length" "1,1,1,2")])
2596
2597 ;; These patterns originally accepted general_operands, however, slightly
2598 ;; better code is generated by only accepting register_operands, and then
2599 ;; letting combine generate the lh and lb insns.
2600
2601 (define_expand "extendhidi2"
2602 [(set (match_operand:DI 0 "register_operand" "")
2603 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
2604 "TARGET_64BIT"
2605 "
2606 {
2607 if (optimize && GET_CODE (operands[1]) == MEM)
2608 operands[1] = force_not_mem (operands[1]);
2609
2610 if (GET_CODE (operands[1]) != MEM)
2611 {
2612 rtx op1 = gen_lowpart (DImode, operands[1]);
2613 rtx temp = gen_reg_rtx (DImode);
2614 rtx shift = gen_rtx (CONST_INT, VOIDmode, 48);
2615
2616 emit_insn (gen_ashldi3 (temp, op1, shift));
2617 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2618 DONE;
2619 }
2620 }")
2621
2622 (define_insn "extendhidi2_internal"
2623 [(set (match_operand:DI 0 "register_operand" "=d,d")
2624 (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
2625 "TARGET_64BIT"
2626 "* return mips_move_1word (operands, insn, FALSE);"
2627 [(set_attr "type" "load")
2628 (set_attr "mode" "DI")
2629 (set_attr "length" "1,2")])
2630
2631 (define_expand "extendhisi2"
2632 [(set (match_operand:SI 0 "register_operand" "")
2633 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2634 ""
2635 "
2636 {
2637 if (optimize && GET_CODE (operands[1]) == MEM)
2638 operands[1] = force_not_mem (operands[1]);
2639
2640 if (GET_CODE (operands[1]) != MEM)
2641 {
2642 rtx op1 = gen_lowpart (SImode, operands[1]);
2643 rtx temp = gen_reg_rtx (SImode);
2644 rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
2645
2646 emit_insn (gen_ashlsi3 (temp, op1, shift));
2647 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2648 DONE;
2649 }
2650 }")
2651
2652 (define_insn "extendhisi2_internal"
2653 [(set (match_operand:SI 0 "register_operand" "=d,d")
2654 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
2655 ""
2656 "* return mips_move_1word (operands, insn, FALSE);"
2657 [(set_attr "type" "load")
2658 (set_attr "mode" "SI")
2659 (set_attr "length" "1,2")])
2660
2661 (define_expand "extendqihi2"
2662 [(set (match_operand:HI 0 "register_operand" "")
2663 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2664 ""
2665 "
2666 {
2667 if (optimize && GET_CODE (operands[1]) == MEM)
2668 operands[1] = force_not_mem (operands[1]);
2669
2670 if (GET_CODE (operands[1]) != MEM)
2671 {
2672 rtx op0 = gen_lowpart (SImode, operands[0]);
2673 rtx op1 = gen_lowpart (SImode, operands[1]);
2674 rtx temp = gen_reg_rtx (SImode);
2675 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2676
2677 emit_insn (gen_ashlsi3 (temp, op1, shift));
2678 emit_insn (gen_ashrsi3 (op0, temp, shift));
2679 DONE;
2680 }
2681 }")
2682
2683 (define_insn "extendqihi2_internal"
2684 [(set (match_operand:HI 0 "register_operand" "=d,d")
2685 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
2686 ""
2687 "* return mips_move_1word (operands, insn, FALSE);"
2688 [(set_attr "type" "load")
2689 (set_attr "mode" "SI")
2690 (set_attr "length" "1,2")])
2691
2692
2693 (define_expand "extendqisi2"
2694 [(set (match_operand:SI 0 "register_operand" "")
2695 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2696 ""
2697 "
2698 {
2699 if (optimize && GET_CODE (operands[1]) == MEM)
2700 operands[1] = force_not_mem (operands[1]);
2701
2702 if (GET_CODE (operands[1]) != MEM)
2703 {
2704 rtx op1 = gen_lowpart (SImode, operands[1]);
2705 rtx temp = gen_reg_rtx (SImode);
2706 rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2707
2708 emit_insn (gen_ashlsi3 (temp, op1, shift));
2709 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2710 DONE;
2711 }
2712 }")
2713
2714 (define_insn "extendqisi2_insn"
2715 [(set (match_operand:SI 0 "register_operand" "=d,d")
2716 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
2717 ""
2718 "* return mips_move_1word (operands, insn, FALSE);"
2719 [(set_attr "type" "load")
2720 (set_attr "mode" "SI")
2721 (set_attr "length" "1,2")])
2722
2723 (define_expand "extendqidi2"
2724 [(set (match_operand:DI 0 "register_operand" "")
2725 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
2726 "TARGET_64BIT"
2727 "
2728 {
2729 if (optimize && GET_CODE (operands[1]) == MEM)
2730 operands[1] = force_not_mem (operands[1]);
2731
2732 if (GET_CODE (operands[1]) != MEM)
2733 {
2734 rtx op1 = gen_lowpart (DImode, operands[1]);
2735 rtx temp = gen_reg_rtx (DImode);
2736 rtx shift = gen_rtx (CONST_INT, VOIDmode, 56);
2737
2738 emit_insn (gen_ashldi3 (temp, op1, shift));
2739 emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2740 DONE;
2741 }
2742 }")
2743
2744 (define_insn "extendqidi2_insn"
2745 [(set (match_operand:DI 0 "register_operand" "=d,d")
2746 (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
2747 "TARGET_64BIT"
2748 "* return mips_move_1word (operands, insn, FALSE);"
2749 [(set_attr "type" "load")
2750 (set_attr "mode" "DI")
2751 (set_attr "length" "1,2")])
2752
2753
2754 (define_insn "extendsfdf2"
2755 [(set (match_operand:DF 0 "register_operand" "=f")
2756 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2757 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2758 "cvt.d.s\\t%0,%1"
2759 [(set_attr "type" "fcvt")
2760 (set_attr "mode" "DF")
2761 (set_attr "length" "1")])
2762
2763 \f
2764
2765 ;;
2766 ;; ....................
2767 ;;
2768 ;; CONVERSIONS
2769 ;;
2770 ;; ....................
2771
2772 ;; The SImode scratch register can not be shared with address regs used for
2773 ;; operand zero, because then the address in the move instruction will be
2774 ;; clobbered. We mark the scratch register as early clobbered to prevent this.
2775
2776 ;; We need the ?X in alternative 1 so that it will be choosen only if the
2777 ;; destination is a floating point register. Otherwise, alternative 1 can
2778 ;; have lower cost than alternative 0 (because there is one less loser), and
2779 ;; can be choosen when it won't work (because integral reloads into FP
2780 ;; registers are not supported).
2781
2782 (define_insn "fix_truncdfsi2"
2783 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2784 (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2785 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2786 (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
2787 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2788 "*
2789 {
2790 rtx xoperands[10];
2791
2792 if (which_alternative == 1)
2793 return \"trunc.w.d %0,%1,%2\";
2794
2795 output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
2796
2797 xoperands[0] = operands[0];
2798 xoperands[1] = operands[3];
2799 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2800 return \"\";
2801 }"
2802 [(set_attr "type" "fcvt")
2803 (set_attr "mode" "DF")
2804 (set_attr "length" "11,9,10,11")])
2805
2806
2807 (define_insn "fix_truncsfsi2"
2808 [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2809 (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2810 (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2811 (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
2812 "TARGET_HARD_FLOAT"
2813 "*
2814 {
2815 rtx xoperands[10];
2816
2817 if (which_alternative == 1)
2818 return \"trunc.w.s %0,%1,%2\";
2819
2820 output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
2821
2822 xoperands[0] = operands[0];
2823 xoperands[1] = operands[3];
2824 output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2825 return \"\";
2826 }"
2827 [(set_attr "type" "fcvt")
2828 (set_attr "mode" "SF")
2829 (set_attr "length" "11,9,10,11")])
2830
2831
2832 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
2833 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
2834 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
2835
2836 ;;; Deleting this means that we now need two libgcc2.a libraries. One for
2837 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
2838
2839 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
2840
2841 (define_insn "fix_truncdfdi2"
2842 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2843 (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2844 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
2845 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2846 "*
2847 {
2848 rtx xoperands[10];
2849
2850 if (which_alternative == 1)
2851 return \"trunc.l.d %0,%1\";
2852
2853 output_asm_insn (\"trunc.l.d %2,%1\", operands);
2854
2855 xoperands[0] = operands[0];
2856 xoperands[1] = operands[2];
2857 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2858 return \"\";
2859 }"
2860 [(set_attr "type" "fcvt")
2861 (set_attr "mode" "DF")
2862 (set_attr "length" "2,1,2,3")])
2863
2864
2865 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
2866 ;;; but not in the chapter that describes the FPU. It is not mentioned at all
2867 ;;; in the 1991 manuals. The r4000 at Cygnus does not have this instruction.
2868 (define_insn "fix_truncsfdi2"
2869 [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2870 (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2871 (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
2872 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2873 "*
2874 {
2875 rtx xoperands[10];
2876
2877 if (which_alternative == 1)
2878 return \"trunc.l.s %0,%1\";
2879
2880 output_asm_insn (\"trunc.l.s %2,%1\", operands);
2881
2882 xoperands[0] = operands[0];
2883 xoperands[1] = operands[2];
2884 output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2885 return \"\";
2886 }"
2887 [(set_attr "type" "fcvt")
2888 (set_attr "mode" "SF")
2889 (set_attr "length" "2,1,2,3")])
2890
2891
2892 (define_insn "floatsidf2"
2893 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2894 (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2895 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2896 "*
2897 {
2898 dslots_load_total++;
2899 if (GET_CODE (operands[1]) == MEM)
2900 return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
2901
2902 return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
2903 }"
2904 [(set_attr "type" "fcvt")
2905 (set_attr "mode" "DF")
2906 (set_attr "length" "3,4,3")])
2907
2908
2909 (define_insn "floatdidf2"
2910 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2911 (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
2912 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2913 "*
2914 {
2915 dslots_load_total++;
2916 if (GET_CODE (operands[1]) == MEM)
2917 return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
2918
2919 return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
2920 }"
2921 [(set_attr "type" "fcvt")
2922 (set_attr "mode" "DF")
2923 (set_attr "length" "3,4,3")])
2924
2925
2926 (define_insn "floatsisf2"
2927 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2928 (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2929 "TARGET_HARD_FLOAT"
2930 "*
2931 {
2932 dslots_load_total++;
2933 if (GET_CODE (operands[1]) == MEM)
2934 return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
2935
2936 return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
2937 }"
2938 [(set_attr "type" "fcvt")
2939 (set_attr "mode" "SF")
2940 (set_attr "length" "3,4,3")])
2941
2942
2943 (define_insn "floatdisf2"
2944 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2945 (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
2946 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2947 "*
2948 {
2949 dslots_load_total++;
2950 if (GET_CODE (operands[1]) == MEM)
2951 return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
2952
2953 return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
2954 }"
2955 [(set_attr "type" "fcvt")
2956 (set_attr "mode" "SF")
2957 (set_attr "length" "3,4,3")])
2958
2959
2960 (define_expand "fixuns_truncdfsi2"
2961 [(set (match_operand:SI 0 "register_operand" "")
2962 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
2963 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2964 "
2965 {
2966 rtx reg1 = gen_reg_rtx (DFmode);
2967 rtx reg2 = gen_reg_rtx (DFmode);
2968 rtx reg3 = gen_reg_rtx (SImode);
2969 rtx label1 = gen_label_rtx ();
2970 rtx label2 = gen_label_rtx ();
2971 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2972
2973 if (reg1) /* turn off complaints about unreached code */
2974 {
2975 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2976 do_pending_stack_adjust ();
2977
2978 emit_insn (gen_cmpdf (operands[1], reg1));
2979 emit_jump_insn (gen_bge (label1));
2980
2981 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2982 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2983 gen_rtx (LABEL_REF, VOIDmode, label2)));
2984 emit_barrier ();
2985
2986 emit_label (label1);
2987 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
2988 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2989
2990 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2991 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2992
2993 emit_label (label2);
2994
2995 /* allow REG_NOTES to be set on last insn (labels don't have enough
2996 fields, and can't be used for REG_NOTES anyway). */
2997 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2998 DONE;
2999 }
3000 }")
3001
3002
3003 (define_expand "fixuns_truncdfdi2"
3004 [(set (match_operand:DI 0 "register_operand" "")
3005 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
3006 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3007 "
3008 {
3009 rtx reg1 = gen_reg_rtx (DFmode);
3010 rtx reg2 = gen_reg_rtx (DFmode);
3011 rtx reg3 = gen_reg_rtx (DImode);
3012 rtx label1 = gen_label_rtx ();
3013 rtx label2 = gen_label_rtx ();
3014 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
3015
3016 if (reg1) /* turn off complaints about unreached code */
3017 {
3018 emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
3019 do_pending_stack_adjust ();
3020
3021 emit_insn (gen_cmpdf (operands[1], reg1));
3022 emit_jump_insn (gen_bge (label1));
3023
3024 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3025 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3026 gen_rtx (LABEL_REF, VOIDmode, label2)));
3027 emit_barrier ();
3028
3029 emit_label (label1);
3030 emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
3031 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3032 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3033
3034 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3035 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3036
3037 emit_label (label2);
3038
3039 /* allow REG_NOTES to be set on last insn (labels don't have enough
3040 fields, and can't be used for REG_NOTES anyway). */
3041 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3042 DONE;
3043 }
3044 }")
3045
3046
3047 (define_expand "fixuns_truncsfsi2"
3048 [(set (match_operand:SI 0 "register_operand" "")
3049 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
3050 "TARGET_HARD_FLOAT"
3051 "
3052 {
3053 rtx reg1 = gen_reg_rtx (SFmode);
3054 rtx reg2 = gen_reg_rtx (SFmode);
3055 rtx reg3 = gen_reg_rtx (SImode);
3056 rtx label1 = gen_label_rtx ();
3057 rtx label2 = gen_label_rtx ();
3058 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
3059
3060 if (reg1) /* turn off complaints about unreached code */
3061 {
3062 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
3063 do_pending_stack_adjust ();
3064
3065 emit_insn (gen_cmpsf (operands[1], reg1));
3066 emit_jump_insn (gen_bge (label1));
3067
3068 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3069 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3070 gen_rtx (LABEL_REF, VOIDmode, label2)));
3071 emit_barrier ();
3072
3073 emit_label (label1);
3074 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
3075 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3076
3077 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3078 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3079
3080 emit_label (label2);
3081
3082 /* allow REG_NOTES to be set on last insn (labels don't have enough
3083 fields, and can't be used for REG_NOTES anyway). */
3084 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3085 DONE;
3086 }
3087 }")
3088
3089
3090 (define_expand "fixuns_truncsfdi2"
3091 [(set (match_operand:DI 0 "register_operand" "")
3092 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
3093 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3094 "
3095 {
3096 rtx reg1 = gen_reg_rtx (SFmode);
3097 rtx reg2 = gen_reg_rtx (SFmode);
3098 rtx reg3 = gen_reg_rtx (DImode);
3099 rtx label1 = gen_label_rtx ();
3100 rtx label2 = gen_label_rtx ();
3101 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
3102
3103 if (reg1) /* turn off complaints about unreached code */
3104 {
3105 emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
3106 do_pending_stack_adjust ();
3107
3108 emit_insn (gen_cmpsf (operands[1], reg1));
3109 emit_jump_insn (gen_bge (label1));
3110
3111 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3112 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3113 gen_rtx (LABEL_REF, VOIDmode, label2)));
3114 emit_barrier ();
3115
3116 emit_label (label1);
3117 emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
3118 emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3119 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3120
3121 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3122 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3123
3124 emit_label (label2);
3125
3126 /* allow REG_NOTES to be set on last insn (labels don't have enough
3127 fields, and can't be used for REG_NOTES anyway). */
3128 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3129 DONE;
3130 }
3131 }")
3132
3133 \f
3134 ;;
3135 ;; ....................
3136 ;;
3137 ;; DATA MOVEMENT
3138 ;;
3139 ;; ....................
3140
3141 ;; Bit field extract patterns which use lwl/lwr.
3142
3143 ;; ??? There should be DImode variants for 64 bit code, but the current
3144 ;; bitfield scheme can't handle that. We would need to add new optabs
3145 ;; in order to make that work.
3146
3147 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
3148 ;; It isn't clear whether this will give better code.
3149
3150 (define_expand "extv"
3151 [(set (match_operand:SI 0 "register_operand" "")
3152 (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
3153 (match_operand:SI 2 "immediate_operand" "")
3154 (match_operand:SI 3 "immediate_operand" "")))]
3155 ""
3156 "
3157 {
3158 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3159 then fail. */
3160 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
3161 FAIL;
3162
3163 /* This can happen for a 64 bit target, when extracting a value from
3164 a 64 bit union member. extract_bit_field doesn't verify that our
3165 source matches the predicate, so we force it to be a MEM here. */
3166 if (GET_CODE (operands[1]) != MEM)
3167 FAIL;
3168
3169 /* Change the mode to BLKmode for aliasing purposes. */
3170 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
3171
3172 /* Otherwise, emit a lwl/lwr pair to load the value. */
3173 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
3174 DONE;
3175 }")
3176
3177 (define_expand "extzv"
3178 [(set (match_operand:SI 0 "register_operand" "")
3179 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
3180 (match_operand:SI 2 "immediate_operand" "")
3181 (match_operand:SI 3 "immediate_operand" "")))]
3182 ""
3183 "
3184 {
3185 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3186 then fail. */
3187 if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
3188 FAIL;
3189
3190 /* This can happen for a 64 bit target, when extracting a value from
3191 a 64 bit union member. extract_bit_field doesn't verify that our
3192 source matches the predicate, so we force it to be a MEM here. */
3193 if (GET_CODE (operands[1]) != MEM)
3194 FAIL;
3195
3196 /* Change the mode to BLKmode for aliasing purposes. */
3197 operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
3198
3199 /* Otherwise, emit a lwl/lwr pair to load the value. */
3200 emit_insn (gen_movsi_ulw (operands[0], operands[1]));
3201 DONE;
3202 }")
3203
3204 (define_expand "insv"
3205 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
3206 (match_operand:SI 1 "immediate_operand" "")
3207 (match_operand:SI 2 "immediate_operand" ""))
3208 (match_operand:SI 3 "register_operand" ""))]
3209 ""
3210 "
3211 {
3212 /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3213 then fail. */
3214 if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
3215 FAIL;
3216
3217 /* This can happen for a 64 bit target, when storing into a 32 bit union
3218 member. store_bit_field doesn't verify that our target matches the
3219 predicate, so we force it to be a MEM here. */
3220 if (GET_CODE (operands[0]) != MEM)
3221 FAIL;
3222
3223 /* Change the mode to BLKmode for aliasing purposes. */
3224 operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
3225
3226 /* Otherwise, emit a swl/swr pair to load the value. */
3227 emit_insn (gen_movsi_usw (operands[0], operands[3]));
3228 DONE;
3229 }")
3230
3231 ;; unaligned word moves generated by the bit field patterns
3232
3233 (define_insn "movsi_ulw"
3234 [(set (match_operand:SI 0 "register_operand" "=&d,&d")
3235 (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
3236 ""
3237 "*
3238 {
3239 rtx offset = const0_rtx;
3240 rtx addr = XEXP (operands[1], 0);
3241 rtx mem_addr = eliminate_constant_term (addr, &offset);
3242 char *ret;
3243
3244 if (TARGET_STATS)
3245 mips_count_memory_refs (operands[1], 2);
3246
3247 /* The stack/frame pointers are always aligned, so we can convert
3248 to the faster lw if we are referencing an aligned stack location. */
3249
3250 if ((INTVAL (offset) & 3) == 0
3251 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
3252 ret = \"lw\\t%0,%1\";
3253 else
3254 ret = \"ulw\\t%0,%1\";
3255
3256 return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
3257 }"
3258 [(set_attr "type" "load,load")
3259 (set_attr "mode" "SI")
3260 (set_attr "length" "2,4")])
3261
3262 (define_insn "movsi_usw"
3263 [(set (match_operand:BLK 0 "memory_operand" "=R,o")
3264 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
3265 ""
3266 "*
3267 {
3268 rtx offset = const0_rtx;
3269 rtx addr = XEXP (operands[0], 0);
3270 rtx mem_addr = eliminate_constant_term (addr, &offset);
3271
3272 if (TARGET_STATS)
3273 mips_count_memory_refs (operands[0], 2);
3274
3275 /* The stack/frame pointers are always aligned, so we can convert
3276 to the faster sw if we are referencing an aligned stack location. */
3277
3278 if ((INTVAL (offset) & 3) == 0
3279 && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
3280 return \"sw\\t%1,%0\";
3281
3282 return \"usw\\t%z1,%0\";
3283 }"
3284 [(set_attr "type" "store")
3285 (set_attr "mode" "SI")
3286 (set_attr "length" "2,4")])
3287
3288 ;; These two patterns support loading addresses with two instructions instead
3289 ;; of using the macro instruction la.
3290
3291 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
3292 ;; unnecessary.
3293
3294 (define_insn "high"
3295 [(set (match_operand:SI 0 "register_operand" "=r")
3296 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
3297 "mips_split_addresses"
3298 "lui\\t%0,%%hi(%1) # high"
3299 [(set_attr "type" "move")
3300 (set_attr "length" "1")])
3301
3302 (define_insn "low"
3303 [(set (match_operand:SI 0 "register_operand" "=r")
3304 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
3305 (match_operand:SI 2 "immediate_operand" "")))]
3306 "mips_split_addresses"
3307 "addiu\\t%0,%1,%%lo(%2) # low"
3308 [(set_attr "type" "arith")
3309 (set_attr "mode" "SI")
3310 (set_attr "length" "1")])
3311
3312 ;; 64-bit integer moves
3313
3314 ;; Unlike most other insns, the move insns can't be split with
3315 ;; different predicates, because register spilling and other parts of
3316 ;; the compiler, have memoized the insn number already.
3317
3318 (define_expand "movdi"
3319 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3320 (match_operand:DI 1 "general_operand" ""))]
3321 ""
3322 "
3323 {
3324 if (mips_split_addresses && mips_check_split (operands[1], DImode))
3325 {
3326 enum machine_mode mode = GET_MODE (operands[0]);
3327 rtx tem = ((reload_in_progress | reload_completed)
3328 ? operands[0] : gen_reg_rtx (mode));
3329
3330 emit_insn (gen_rtx (SET, VOIDmode, tem,
3331 gen_rtx (HIGH, mode, operands[1])));
3332
3333 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
3334 }
3335
3336 /* If we are generating embedded PIC code, and we are referring to a
3337 symbol in the .text section, we must use an offset from the start
3338 of the function. */
3339 if (TARGET_EMBEDDED_PIC
3340 && (GET_CODE (operands[1]) == LABEL_REF
3341 || (GET_CODE (operands[1]) == SYMBOL_REF
3342 && ! SYMBOL_REF_FLAG (operands[1]))))
3343 {
3344 rtx temp;
3345
3346 temp = embedded_pic_offset (operands[1]);
3347 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
3348 force_reg (DImode, temp));
3349 emit_move_insn (operands[0], force_reg (DImode, temp));
3350 DONE;
3351 }
3352
3353 /* If operands[1] is a constant address illegal for pic, then we need to
3354 handle it just like LEGITIMIZE_ADDRESS does. */
3355 if (flag_pic && pic_address_needs_scratch (operands[1]))
3356 {
3357 rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
3358 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3359
3360 if (! SMALL_INT (temp2))
3361 temp2 = force_reg (DImode, temp2);
3362
3363 emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
3364 DONE;
3365 }
3366
3367 if ((reload_in_progress | reload_completed) == 0
3368 && !register_operand (operands[0], DImode)
3369 && !register_operand (operands[1], DImode)
3370 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3371 && operands[1] != CONST0_RTX (DImode))
3372 {
3373 rtx temp = force_reg (DImode, operands[1]);
3374 emit_move_insn (operands[0], temp);
3375 DONE;
3376 }
3377 }")
3378
3379 (define_insn "movdi_internal"
3380 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
3381 (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
3382 "!TARGET_64BIT
3383 && (register_operand (operands[0], DImode)
3384 || register_operand (operands[1], DImode)
3385 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3386 || operands[1] == CONST0_RTX (DImode))"
3387 "* return mips_move_2words (operands, insn); "
3388 [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo")
3389 (set_attr "mode" "DI")
3390 (set_attr "length" "2,4,2,4,2,4,2,2,2")])
3391
3392 (define_split
3393 [(set (match_operand:DI 0 "register_operand" "")
3394 (match_operand:DI 1 "register_operand" ""))]
3395 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3396 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3397 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3398
3399 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
3400 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
3401 "")
3402
3403 (define_insn "movdi_internal2"
3404 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
3405 (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
3406 "TARGET_64BIT
3407 && (register_operand (operands[0], DImode)
3408 || se_register_operand (operands[1], DImode)
3409 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3410 || operands[1] == CONST0_RTX (DImode))"
3411 "* return mips_move_2words (operands, insn); "
3412 [(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
3413 (set_attr "mode" "DI")
3414 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,2")])
3415
3416 ;; Handle input reloads in DImode.
3417 ;; This is mainly to handle reloading HILO_REGNUM. Note that we may
3418 ;; see it as the source or the destination, depending upon which way
3419 ;; reload handles the instruction.
3420 ;; Making the second operand TImode is a trick. The compiler may
3421 ;; reuse the same register for operand 0 and operand 2. Using TImode
3422 ;; gives us two registers, so we can always use the one which is not
3423 ;; used.
3424
3425 (define_expand "reload_indi"
3426 [(set (match_operand:DI 0 "register_operand" "=b")
3427 (match_operand:DI 1 "movdi_operand" "b"))
3428 (clobber (match_operand:TI 2 "register_operand" "=&d"))]
3429 "TARGET_64BIT"
3430 "
3431 {
3432 rtx scratch = gen_rtx (REG, DImode,
3433 (REGNO (operands[0]) == REGNO (operands[2])
3434 ? REGNO (operands[2]) + 1
3435 : REGNO (operands[2])));
3436
3437 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3438 {
3439 if (GET_CODE (operands[1]) == MEM)
3440 {
3441 rtx memword, offword, hiword, loword;
3442
3443 scratch = gen_rtx (REG, SImode, REGNO (scratch));
3444 memword = change_address (operands[1], SImode, NULL_RTX);
3445 offword = change_address (adj_offsettable_operand (operands[1], 4),
3446 SImode, NULL_RTX);
3447 if (BYTES_BIG_ENDIAN)
3448 {
3449 hiword = memword;
3450 loword = offword;
3451 }
3452 else
3453 {
3454 hiword = offword;
3455 loword = memword;
3456 }
3457 emit_move_insn (scratch, hiword);
3458 emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
3459 emit_move_insn (scratch, loword);
3460 emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
3461 }
3462 else
3463 {
3464 emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
3465 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
3466 emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
3467 emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
3468 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
3469 }
3470 DONE;
3471 }
3472 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3473 {
3474 emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
3475 emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
3476 emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
3477 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
3478 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3479 emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
3480 DONE;
3481 }
3482 /* This handles moves between a float register and HI/LO. */
3483 emit_move_insn (scratch, operands[1]);
3484 emit_move_insn (operands[0], scratch);
3485 DONE;
3486 }")
3487
3488 ;; Handle output reloads in DImode.
3489
3490 (define_expand "reload_outdi"
3491 [(set (match_operand:DI 0 "general_operand" "=b")
3492 (match_operand:DI 1 "se_register_operand" "b"))
3493 (clobber (match_operand:DI 2 "register_operand" "=&d"))]
3494 "TARGET_64BIT"
3495 "
3496 {
3497 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3498 {
3499 emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
3500 emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), operands[2]));
3501 emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
3502 emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
3503 emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), operands[2]));
3504 DONE;
3505 }
3506 if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3507 {
3508 if (GET_CODE (operands[0]) == MEM)
3509 {
3510 rtx scratch, memword, offword, hiword, loword;
3511
3512 scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
3513 memword = change_address (operands[0], SImode, NULL_RTX);
3514 offword = change_address (adj_offsettable_operand (operands[0], 4),
3515 SImode, NULL_RTX);
3516 if (BYTES_BIG_ENDIAN)
3517 {
3518 hiword = memword;
3519 loword = offword;
3520 }
3521 else
3522 {
3523 hiword = offword;
3524 loword = memword;
3525 }
3526 emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
3527 emit_move_insn (hiword, scratch);
3528 emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
3529 emit_move_insn (loword, scratch);
3530 }
3531 else
3532 {
3533 emit_insn (gen_movdi (operands[2], gen_rtx (REG, DImode, 65)));
3534 emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
3535 emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
3536 emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
3537 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3538 emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
3539 }
3540 DONE;
3541 }
3542 /* This handles moves between a float register and HI/LO. */
3543 emit_move_insn (operands[2], operands[1]);
3544 emit_move_insn (operands[0], operands[2]);
3545 DONE;
3546 }")
3547
3548 ;; 32-bit Integer moves
3549
3550 (define_split
3551 [(set (match_operand:SI 0 "register_operand" "")
3552 (match_operand:SI 1 "large_int" ""))]
3553 "!TARGET_DEBUG_D_MODE"
3554 [(set (match_dup 0)
3555 (match_dup 2))
3556 (set (match_dup 0)
3557 (ior:SI (match_dup 0)
3558 (match_dup 3)))]
3559 "
3560 {
3561 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
3562 operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
3563 }")
3564
3565 ;; Unlike most other insns, the move insns can't be split with
3566 ;; different predicates, because register spilling and other parts of
3567 ;; the compiler, have memoized the insn number already.
3568
3569 (define_expand "movsi"
3570 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3571 (match_operand:SI 1 "general_operand" ""))]
3572 ""
3573 "
3574 {
3575 if (mips_split_addresses && mips_check_split (operands[1], SImode))
3576 {
3577 enum machine_mode mode = GET_MODE (operands[0]);
3578 rtx tem = ((reload_in_progress | reload_completed)
3579 ? operands[0] : gen_reg_rtx (mode));
3580
3581 emit_insn (gen_rtx (SET, VOIDmode, tem,
3582 gen_rtx (HIGH, mode, operands[1])));
3583
3584 operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
3585 }
3586
3587 /* If we are generating embedded PIC code, and we are referring to a
3588 symbol in the .text section, we must use an offset from the start
3589 of the function. */
3590 if (TARGET_EMBEDDED_PIC
3591 && (GET_CODE (operands[1]) == LABEL_REF
3592 || (GET_CODE (operands[1]) == SYMBOL_REF
3593 && ! SYMBOL_REF_FLAG (operands[1]))))
3594 {
3595 rtx temp;
3596
3597 temp = embedded_pic_offset (operands[1]);
3598 temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
3599 force_reg (SImode, temp));
3600 emit_move_insn (operands[0], force_reg (SImode, temp));
3601 DONE;
3602 }
3603
3604 /* If operands[1] is a constant address invalid for pic, then we need to
3605 handle it just like LEGITIMIZE_ADDRESS does. */
3606 if (flag_pic && pic_address_needs_scratch (operands[1]))
3607 {
3608 rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
3609 rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3610
3611 if (! SMALL_INT (temp2))
3612 temp2 = force_reg (SImode, temp2);
3613
3614 emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
3615 DONE;
3616 }
3617
3618 if ((reload_in_progress | reload_completed) == 0
3619 && !register_operand (operands[0], SImode)
3620 && !register_operand (operands[1], SImode)
3621 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3622 {
3623 rtx temp = force_reg (SImode, operands[1]);
3624 emit_move_insn (operands[0], temp);
3625 DONE;
3626 }
3627 }")
3628
3629 ;; The difference between these two is whether or not ints are allowed
3630 ;; in FP registers (off by default, use -mdebugh to enable).
3631
3632 (define_insn "movsi_internal1"
3633 [(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")
3634 (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"))]
3635 "TARGET_DEBUG_H_MODE
3636 && (register_operand (operands[0], SImode)
3637 || register_operand (operands[1], SImode)
3638 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3639 "* return mips_move_1word (operands, insn, FALSE);"
3640 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
3641 (set_attr "mode" "SI")
3642 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
3643
3644 (define_insn "movsi_internal2"
3645 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
3646 (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
3647 "!TARGET_DEBUG_H_MODE
3648 && (register_operand (operands[0], SImode)
3649 || register_operand (operands[1], SImode)
3650 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3651 "* return mips_move_1word (operands, insn, FALSE);"
3652 [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
3653 (set_attr "mode" "SI")
3654 (set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
3655
3656 ;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
3657 ;; order to set the sign bit correctly in the HI register.
3658
3659 (define_expand "reload_outsi"
3660 [(set (match_operand:SI 0 "general_operand" "=b")
3661 (match_operand:SI 1 "register_operand" "d"))
3662 (clobber (match_operand:SI 2 "register_operand" "=&d"))]
3663 "TARGET_64BIT"
3664 "
3665 {
3666 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3667 {
3668 emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
3669 emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
3670 emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
3671 DONE;
3672 }
3673 /* This handles moves between a float register and HI/LO. */
3674 emit_move_insn (operands[2], operands[1]);
3675 emit_move_insn (operands[0], operands[2]);
3676 DONE;
3677 }")
3678
3679 ;; This insn handles moving CCmode values. It's really just a
3680 ;; slightly simplified copy of movsi_internal2, with additional cases
3681 ;; to move a condition register to a general register and to move
3682 ;; between the general registers and the floating point registers.
3683
3684 (define_insn "movcc"
3685 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
3686 (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
3687 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3688 "* return mips_move_1word (operands, insn, FALSE);"
3689 [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
3690 (set_attr "mode" "SI")
3691 (set_attr "length" "2,1,1,2,1,2,1,1,1,1,2,1,2")])
3692
3693 ;; Reload condition code registers. These need scratch registers.
3694
3695 (define_expand "reload_incc"
3696 [(set (match_operand:CC 0 "register_operand" "=z")
3697 (match_operand:CC 1 "general_operand" "z"))
3698 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3699 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3700 "
3701 {
3702 rtx source;
3703 rtx fp1, fp2;
3704
3705 /* This is called when are copying some value into a condition code
3706 register. Operand 0 is the condition code register. Operand 1
3707 is the source. Operand 2 is a scratch register; we use TFmode
3708 because we actually need two floating point registers. */
3709 if (! ST_REG_P (true_regnum (operands[0]))
3710 || ! FP_REG_P (true_regnum (operands[2])))
3711 abort ();
3712
3713 /* We need to get the source in SFmode so that the insn is
3714 recognized. */
3715 if (GET_CODE (operands[1]) == MEM)
3716 source = change_address (operands[1], SFmode, NULL_RTX);
3717 else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
3718 source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
3719 else
3720 source = operands[1];
3721
3722 fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
3723 fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
3724
3725 emit_insn (gen_move_insn (fp1, source));
3726 emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
3727 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
3728 gen_rtx (LT, CCmode, fp2, fp1)));
3729
3730 DONE;
3731 }")
3732
3733 (define_expand "reload_outcc"
3734 [(set (match_operand:CC 0 "general_operand" "=z")
3735 (match_operand:CC 1 "register_operand" "z"))
3736 (clobber (match_operand:CC 2 "register_operand" "=&d"))]
3737 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3738 "
3739 {
3740 /* This is called when we are copying a condition code register out
3741 to save it somewhere. Operand 0 should be the location we are
3742 going to save it to. Operand 1 should be the condition code
3743 register. Operand 2 should be a scratch general purpose register
3744 created for us by reload. The mips_secondary_reload_class
3745 function should have told reload that we don't need a scratch
3746 register if the destination is a general purpose register anyhow. */
3747 if (ST_REG_P (true_regnum (operands[0]))
3748 || GP_REG_P (true_regnum (operands[0]))
3749 || ! ST_REG_P (true_regnum (operands[1]))
3750 || ! GP_REG_P (true_regnum (operands[2])))
3751 abort ();
3752
3753 /* All we have to do is copy the value from the condition code to
3754 the data register, which movcc can handle, and then store the
3755 value into the real final destination. */
3756 emit_insn (gen_move_insn (operands[2], operands[1]));
3757 emit_insn (gen_move_insn (operands[0], operands[2]));
3758
3759 DONE;
3760 }")
3761
3762 ;; MIPS4 supports loading and storing a floating point register from
3763 ;; the sum of two general registers. We use two versions for each of
3764 ;; these four instructions: one where the two general registers are
3765 ;; SImode, and one where they are DImode. This is because general
3766 ;; registers will be in SImode when they hold 32 bit values, but,
3767 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3768 ;; instructions will still work correctly.
3769
3770 ;; ??? Perhaps it would be better to support these instructions by
3771 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
3772 ;; these instructions can only be used to load and store floating
3773 ;; point registers, that would probably cause trouble in reload.
3774
3775 (define_insn ""
3776 [(set (match_operand:SF 0 "register_operand" "=f")
3777 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3778 (match_operand:SI 2 "register_operand" "d"))))]
3779 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3780 "lwxc1\\t%0,%1(%2)"
3781 [(set_attr "type" "load")
3782 (set_attr "mode" "SF")
3783 (set_attr "length" "1")])
3784
3785 (define_insn ""
3786 [(set (match_operand:SF 0 "register_operand" "=f")
3787 (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3788 (match_operand:DI 2 "se_register_operand" "d"))))]
3789 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3790 "lwxc1\\t%0,%1(%2)"
3791 [(set_attr "type" "load")
3792 (set_attr "mode" "SF")
3793 (set_attr "length" "1")])
3794
3795 (define_insn ""
3796 [(set (match_operand:DF 0 "register_operand" "=f")
3797 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
3798 (match_operand:SI 2 "register_operand" "d"))))]
3799 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3800 "ldxc1\\t%0,%1(%2)"
3801 [(set_attr "type" "load")
3802 (set_attr "mode" "DF")
3803 (set_attr "length" "1")])
3804
3805 (define_insn ""
3806 [(set (match_operand:DF 0 "register_operand" "=f")
3807 (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3808 (match_operand:DI 2 "se_register_operand" "d"))))]
3809 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3810 "ldxc1\\t%0,%1(%2)"
3811 [(set_attr "type" "load")
3812 (set_attr "mode" "DF")
3813 (set_attr "length" "1")])
3814
3815 (define_insn ""
3816 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3817 (match_operand:SI 2 "register_operand" "d")))
3818 (match_operand:SF 0 "register_operand" "=f"))]
3819 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3820 "swxc1\\t%0,%1(%2)"
3821 [(set_attr "type" "store")
3822 (set_attr "mode" "SF")
3823 (set_attr "length" "1")])
3824
3825 (define_insn ""
3826 [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3827 (match_operand:DI 2 "se_register_operand" "d")))
3828 (match_operand:SF 0 "register_operand" "=f"))]
3829 "mips_isa >= 4 && TARGET_HARD_FLOAT"
3830 "swxc1\\t%0,%1(%2)"
3831 [(set_attr "type" "store")
3832 (set_attr "mode" "SF")
3833 (set_attr "length" "1")])
3834
3835 (define_insn ""
3836 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
3837 (match_operand:SI 2 "register_operand" "d")))
3838 (match_operand:DF 0 "register_operand" "=f"))]
3839 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3840 "sdxc1\\t%0,%1(%2)"
3841 [(set_attr "type" "store")
3842 (set_attr "mode" "DF")
3843 (set_attr "length" "1")])
3844
3845 (define_insn ""
3846 [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3847 (match_operand:DI 2 "se_register_operand" "d")))
3848 (match_operand:DF 0 "register_operand" "=f"))]
3849 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3850 "sdxc1\\t%0,%1(%2)"
3851 [(set_attr "type" "store")
3852 (set_attr "mode" "DF")
3853 (set_attr "length" "1")])
3854
3855 ;; 16-bit Integer moves
3856
3857 ;; Unlike most other insns, the move insns can't be split with
3858 ;; different predicates, because register spilling and other parts of
3859 ;; the compiler, have memoized the insn number already.
3860 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3861
3862 (define_expand "movhi"
3863 [(set (match_operand:HI 0 "nonimmediate_operand" "")
3864 (match_operand:HI 1 "general_operand" ""))]
3865 ""
3866 "
3867 {
3868 if ((reload_in_progress | reload_completed) == 0
3869 && !register_operand (operands[0], HImode)
3870 && !register_operand (operands[1], HImode)
3871 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3872 {
3873 rtx temp = force_reg (HImode, operands[1]);
3874 emit_move_insn (operands[0], temp);
3875 DONE;
3876 }
3877 }")
3878
3879 ;; The difference between these two is whether or not ints are allowed
3880 ;; in FP registers (off by default, use -mdebugh to enable).
3881
3882 (define_insn "movhi_internal1"
3883 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
3884 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3885 "TARGET_DEBUG_H_MODE
3886 && (register_operand (operands[0], HImode)
3887 || register_operand (operands[1], HImode)
3888 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3889 "* return mips_move_1word (operands, insn, TRUE);"
3890 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3891 (set_attr "mode" "HI")
3892 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
3893
3894 (define_insn "movhi_internal2"
3895 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3896 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3897 "!TARGET_DEBUG_H_MODE
3898 && (register_operand (operands[0], HImode)
3899 || register_operand (operands[1], HImode)
3900 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3901 "* return mips_move_1word (operands, insn, TRUE);"
3902 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3903 (set_attr "mode" "HI")
3904 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
3905
3906
3907 ;; 8-bit Integer moves
3908
3909 ;; Unlike most other insns, the move insns can't be split with
3910 ;; different predicates, because register spilling and other parts of
3911 ;; the compiler, have memoized the insn number already.
3912 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3913
3914 (define_expand "movqi"
3915 [(set (match_operand:QI 0 "nonimmediate_operand" "")
3916 (match_operand:QI 1 "general_operand" ""))]
3917 ""
3918 "
3919 {
3920 if ((reload_in_progress | reload_completed) == 0
3921 && !register_operand (operands[0], QImode)
3922 && !register_operand (operands[1], QImode)
3923 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3924 {
3925 rtx temp = force_reg (QImode, operands[1]);
3926 emit_move_insn (operands[0], temp);
3927 DONE;
3928 }
3929 }")
3930
3931 ;; The difference between these two is whether or not ints are allowed
3932 ;; in FP registers (off by default, use -mdebugh to enable).
3933
3934 (define_insn "movqi_internal1"
3935 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
3936 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3937 "TARGET_DEBUG_H_MODE
3938 && (register_operand (operands[0], QImode)
3939 || register_operand (operands[1], QImode)
3940 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3941 "* return mips_move_1word (operands, insn, TRUE);"
3942 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3943 (set_attr "mode" "QI")
3944 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,1")])
3945
3946 (define_insn "movqi_internal2"
3947 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3948 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3949 "!TARGET_DEBUG_H_MODE
3950 && (register_operand (operands[0], QImode)
3951 || register_operand (operands[1], QImode)
3952 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3953 "* return mips_move_1word (operands, insn, TRUE);"
3954 [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3955 (set_attr "mode" "QI")
3956 (set_attr "length" "1,1,1,2,1,2,1,1,1,1")])
3957
3958
3959 ;; 32-bit floating point moves
3960
3961 (define_expand "movsf"
3962 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3963 (match_operand:SF 1 "general_operand" ""))]
3964 ""
3965 "
3966 {
3967 if ((reload_in_progress | reload_completed) == 0
3968 && !register_operand (operands[0], SFmode)
3969 && !register_operand (operands[1], SFmode)
3970 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3971 && operands[1] != CONST0_RTX (SFmode))
3972 {
3973 rtx temp = force_reg (SFmode, operands[1]);
3974 emit_move_insn (operands[0], temp);
3975 DONE;
3976 }
3977 }")
3978
3979 (define_insn "movsf_internal1"
3980 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
3981 (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
3982 "TARGET_HARD_FLOAT
3983 && (register_operand (operands[0], SFmode)
3984 || register_operand (operands[1], SFmode)
3985 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3986 || operands[1] == CONST0_RTX (SFmode))"
3987 "* return mips_move_1word (operands, insn, FALSE);"
3988 [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
3989 (set_attr "mode" "SF")
3990 (set_attr "length" "1,1,1,2,1,2,1,1,1,1,2,1,2")])
3991
3992
3993 (define_insn "movsf_internal2"
3994 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
3995 (match_operand:SF 1 "general_operand" " Gd,R,Fm,d,d"))]
3996 "TARGET_SOFT_FLOAT
3997 && (register_operand (operands[0], SFmode)
3998 || register_operand (operands[1], SFmode)
3999 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4000 || operands[1] == CONST0_RTX (SFmode))"
4001 "* return mips_move_1word (operands, insn, FALSE);"
4002 [(set_attr "type" "move,load,load,store,store")
4003 (set_attr "mode" "SF")
4004 (set_attr "length" "1,1,2,1,2")])
4005
4006
4007 ;; 64-bit floating point moves
4008
4009 (define_expand "movdf"
4010 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4011 (match_operand:DF 1 "general_operand" ""))]
4012 ""
4013 "
4014 {
4015 if ((reload_in_progress | reload_completed) == 0
4016 && !register_operand (operands[0], DFmode)
4017 && !register_operand (operands[1], DFmode)
4018 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4019 && operands[1] != CONST0_RTX (DFmode))
4020 {
4021 rtx temp = force_reg (DFmode, operands[1]);
4022 emit_move_insn (operands[0], temp);
4023 DONE;
4024 }
4025 }")
4026
4027 (define_insn "movdf_internal1"
4028 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
4029 (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,F,*d,*f,*d*G,*R,*o*F,*d,*d"))]
4030 "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
4031 && TARGET_DOUBLE_FLOAT
4032 && (register_operand (operands[0], DFmode)
4033 || register_operand (operands[1], DFmode)
4034 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4035 || operands[1] == CONST0_RTX (DFmode))"
4036 "* return mips_move_2words (operands, insn); "
4037 [(set_attr "type" "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
4038 (set_attr "mode" "DF")
4039 (set_attr "length" "1,2,4,2,4,4,2,2,2,2,4,2,4")])
4040
4041 (define_insn "movdf_internal1a"
4042 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,o,o,f,*d,*d,*d,*o,*R")
4043 (match_operand:DF 1 "general_operand" " f,o,f,G,f,G,F,*F,*o,*R,*d,*d"))]
4044 "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
4045 && TARGET_DOUBLE_FLOAT
4046 && (register_operand (operands[0], DFmode)
4047 || register_operand (operands[1], DFmode))
4048 || (GET_CODE (operands [0]) == MEM
4049 && ((GET_CODE (operands[1]) == CONST_INT
4050 && INTVAL (operands[1]) == 0)
4051 || operands[1] == CONST0_RTX (DFmode)))"
4052 "* return mips_move_2words (operands, insn); "
4053 [(set_attr "type" "move,load,store,store,store,store,load,load,load,load,store,store")
4054 (set_attr "mode" "DF")
4055 (set_attr "length" "1,2,1,1,2,2,2,2,2,1,2,1")])
4056
4057 (define_insn "movdf_internal2"
4058 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,o")
4059 (match_operand:DF 1 "general_operand" "dG,R,oF,d,d"))]
4060 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT)
4061 && (register_operand (operands[0], DFmode)
4062 || register_operand (operands[1], DFmode)
4063 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4064 || operands[1] == CONST0_RTX (DFmode))"
4065 "* return mips_move_2words (operands, insn); "
4066 [(set_attr "type" "move,load,load,store,store")
4067 (set_attr "mode" "DF")
4068 (set_attr "length" "2,2,4,2,4")])
4069
4070 (define_split
4071 [(set (match_operand:DF 0 "register_operand" "")
4072 (match_operand:DF 1 "register_operand" ""))]
4073 "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4074 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4075 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4076 [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4077 (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4078 "")
4079
4080 ;; Instructions to load the global pointer register.
4081 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
4082 ;; uses in front of it. All symbol_refs implicitly use the gp reg.
4083
4084 (define_insn "loadgp"
4085 [(set (reg:DI 28)
4086 (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")] 2))
4087 (clobber (reg:DI 1))]
4088 ""
4089 "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,$25%]"
4090 [(set_attr "type" "move")
4091 (set_attr "mode" "DI")
4092 (set_attr "length" "3")])
4093 \f
4094 ;; Block moves, see mips.c for more details.
4095 ;; Argument 0 is the destination
4096 ;; Argument 1 is the source
4097 ;; Argument 2 is the length
4098 ;; Argument 3 is the alignment
4099
4100 (define_expand "movstrsi"
4101 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
4102 (match_operand:BLK 1 "general_operand" ""))
4103 (use (match_operand:SI 2 "arith32_operand" ""))
4104 (use (match_operand:SI 3 "immediate_operand" ""))])]
4105 ""
4106 "
4107 {
4108 if (operands[0]) /* avoid unused code messages */
4109 {
4110 expand_block_move (operands);
4111 DONE;
4112 }
4113 }")
4114
4115 ;; Insn generated by block moves
4116
4117 (define_insn "movstrsi_internal"
4118 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
4119 (match_operand:BLK 1 "memory_operand" "o")) ;; source
4120 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
4121 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
4122 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
4123 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
4124 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
4125 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
4126 (use (const_int 0))] ;; normal block move
4127 ""
4128 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
4129 [(set_attr "type" "store")
4130 (set_attr "mode" "none")
4131 (set_attr "length" "20")])
4132
4133 ;; Split a block move into 2 parts, the first part is everything
4134 ;; except for the last move, and the second part is just the last
4135 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
4136 ;; fill a delay slot. This also prevents a bug in delayed branches
4137 ;; from showing up, which reuses one of the registers in our clobbers.
4138
4139 (define_split
4140 [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
4141 (mem:BLK (match_operand:SI 1 "register_operand" "")))
4142 (clobber (match_operand:SI 4 "register_operand" ""))
4143 (clobber (match_operand:SI 5 "register_operand" ""))
4144 (clobber (match_operand:SI 6 "register_operand" ""))
4145 (clobber (match_operand:SI 7 "register_operand" ""))
4146 (use (match_operand:SI 2 "small_int" ""))
4147 (use (match_operand:SI 3 "small_int" ""))
4148 (use (const_int 0))]
4149
4150 "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
4151
4152 ;; All but the last move
4153 [(parallel [(set (mem:BLK (match_dup 0))
4154 (mem:BLK (match_dup 1)))
4155 (clobber (match_dup 4))
4156 (clobber (match_dup 5))
4157 (clobber (match_dup 6))
4158 (clobber (match_dup 7))
4159 (use (match_dup 2))
4160 (use (match_dup 3))
4161 (use (const_int 1))])
4162
4163 ;; The last store, so it can fill a delay slot
4164 (parallel [(set (mem:BLK (match_dup 0))
4165 (mem:BLK (match_dup 1)))
4166 (clobber (match_dup 4))
4167 (clobber (match_dup 5))
4168 (clobber (match_dup 6))
4169 (clobber (match_dup 7))
4170 (use (match_dup 2))
4171 (use (match_dup 3))
4172 (use (const_int 2))])]
4173
4174 "")
4175
4176 (define_insn "movstrsi_internal2"
4177 [(set (match_operand:BLK 0 "memory_operand" "=o") ;; destination
4178 (match_operand:BLK 1 "memory_operand" "o")) ;; source
4179 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
4180 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
4181 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
4182 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
4183 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
4184 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
4185 (use (const_int 1))] ;; all but last store
4186 ""
4187 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
4188 [(set_attr "type" "store")
4189 (set_attr "mode" "none")
4190 (set_attr "length" "20")])
4191
4192 (define_insn "movstrsi_internal3"
4193 [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
4194 (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
4195 (clobber (match_scratch:SI 4 "=&d")) ;; temp 1
4196 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2
4197 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3
4198 (clobber (match_scratch:SI 7 "=&d")) ;; temp 4
4199 (use (match_operand:SI 2 "small_int" "I")) ;; # bytes to move
4200 (use (match_operand:SI 3 "small_int" "I")) ;; alignment
4201 (use (const_int 2))] ;; just last store of block move
4202 ""
4203 "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
4204 [(set_attr "type" "store")
4205 (set_attr "mode" "none")
4206 (set_attr "length" "1")])
4207
4208 \f
4209 ;;
4210 ;; ....................
4211 ;;
4212 ;; SHIFTS
4213 ;;
4214 ;; ....................
4215
4216 (define_insn "ashlsi3"
4217 [(set (match_operand:SI 0 "register_operand" "=d")
4218 (ashift:SI (match_operand:SI 1 "register_operand" "d")
4219 (match_operand:SI 2 "arith_operand" "dI")))]
4220 ""
4221 "*
4222 {
4223 if (GET_CODE (operands[2]) == CONST_INT)
4224 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4225
4226 return \"sll\\t%0,%1,%2\";
4227 }"
4228 [(set_attr "type" "arith")
4229 (set_attr "mode" "SI")
4230 (set_attr "length" "1")])
4231
4232
4233 (define_expand "ashldi3"
4234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4235 (ashift:DI (match_operand:DI 1 "se_register_operand" "")
4236 (match_operand:SI 2 "arith_operand" "")))
4237 (clobber (match_dup 3))])]
4238 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4239 "
4240 {
4241 if (TARGET_64BIT)
4242 {
4243 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
4244 operands[2]));
4245 DONE;
4246 }
4247
4248 operands[3] = gen_reg_rtx (SImode);
4249 }")
4250
4251
4252 (define_insn "ashldi3_internal"
4253 [(set (match_operand:DI 0 "register_operand" "=&d")
4254 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4255 (match_operand:SI 2 "register_operand" "d")))
4256 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4257 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4258 "*
4259 {
4260 operands[4] = const0_rtx;
4261 dslots_jump_total += 3;
4262 dslots_jump_filled += 2;
4263
4264 return \"sll\\t%3,%2,26\\n\\
4265 \\tbgez\\t%3,1f\\n\\
4266 \\tsll\\t%M0,%L1,%2\\n\\
4267 \\t%(b\\t3f\\n\\
4268 \\tmove\\t%L0,%z4%)\\n\\
4269 \\n\\
4270 1:\\n\\
4271 \\t%(beq\\t%3,%z4,2f\\n\\
4272 \\tsll\\t%M0,%M1,%2%)\\n\\
4273 \\n\\
4274 \\tsubu\\t%3,%z4,%2\\n\\
4275 \\tsrl\\t%3,%L1,%3\\n\\
4276 \\tor\\t%M0,%M0,%3\\n\\
4277 2:\\n\\
4278 \\tsll\\t%L0,%L1,%2\\n\\
4279 3:\";
4280 }"
4281 [(set_attr "type" "darith")
4282 (set_attr "mode" "SI")
4283 (set_attr "length" "12")])
4284
4285
4286 (define_insn "ashldi3_internal2"
4287 [(set (match_operand:DI 0 "register_operand" "=d")
4288 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4289 (match_operand:SI 2 "small_int" "IJK")))
4290 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4291 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4292 "*
4293 {
4294 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4295 operands[4] = const0_rtx;
4296 return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
4297 }"
4298 [(set_attr "type" "darith")
4299 (set_attr "mode" "DI")
4300 (set_attr "length" "2")])
4301
4302
4303 (define_split
4304 [(set (match_operand:DI 0 "register_operand" "")
4305 (ashift:DI (match_operand:DI 1 "register_operand" "")
4306 (match_operand:SI 2 "small_int" "")))
4307 (clobber (match_operand:SI 3 "register_operand" ""))]
4308 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4309 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4310 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4311 && (INTVAL (operands[2]) & 32) != 0"
4312
4313 [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4314 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4315
4316 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4317
4318
4319 (define_split
4320 [(set (match_operand:DI 0 "register_operand" "")
4321 (ashift:DI (match_operand:DI 1 "register_operand" "")
4322 (match_operand:SI 2 "small_int" "")))
4323 (clobber (match_operand:SI 3 "register_operand" ""))]
4324 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4325 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4326 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4327 && (INTVAL (operands[2]) & 32) != 0"
4328
4329 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4330 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4331
4332 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4333
4334
4335 (define_insn "ashldi3_internal3"
4336 [(set (match_operand:DI 0 "register_operand" "=d")
4337 (ashift:DI (match_operand:DI 1 "register_operand" "d")
4338 (match_operand:SI 2 "small_int" "IJK")))
4339 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4340 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4341 && (INTVAL (operands[2]) & 63) < 32
4342 && (INTVAL (operands[2]) & 63) != 0"
4343 "*
4344 {
4345 int amount = INTVAL (operands[2]);
4346
4347 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4348 operands[4] = const0_rtx;
4349 operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4350
4351 return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
4352 }"
4353 [(set_attr "type" "darith")
4354 (set_attr "mode" "DI")
4355 (set_attr "length" "4")])
4356
4357
4358 (define_split
4359 [(set (match_operand:DI 0 "register_operand" "")
4360 (ashift:DI (match_operand:DI 1 "register_operand" "")
4361 (match_operand:SI 2 "small_int" "")))
4362 (clobber (match_operand:SI 3 "register_operand" ""))]
4363 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4364 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4365 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4366 && (INTVAL (operands[2]) & 63) < 32
4367 && (INTVAL (operands[2]) & 63) != 0"
4368
4369 [(set (subreg:SI (match_dup 0) 1)
4370 (ashift:SI (subreg:SI (match_dup 1) 1)
4371 (match_dup 2)))
4372
4373 (set (match_dup 3)
4374 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4375 (match_dup 4)))
4376
4377 (set (subreg:SI (match_dup 0) 1)
4378 (ior:SI (subreg:SI (match_dup 0) 1)
4379 (match_dup 3)))
4380
4381 (set (subreg:SI (match_dup 0) 0)
4382 (ashift:SI (subreg:SI (match_dup 1) 0)
4383 (match_dup 2)))]
4384 "
4385 {
4386 int amount = INTVAL (operands[2]);
4387 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4388 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4389 }")
4390
4391
4392 (define_split
4393 [(set (match_operand:DI 0 "register_operand" "")
4394 (ashift:DI (match_operand:DI 1 "register_operand" "")
4395 (match_operand:SI 2 "small_int" "")))
4396 (clobber (match_operand:SI 3 "register_operand" ""))]
4397 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4398 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4399 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4400 && (INTVAL (operands[2]) & 63) < 32
4401 && (INTVAL (operands[2]) & 63) != 0"
4402
4403 [(set (subreg:SI (match_dup 0) 0)
4404 (ashift:SI (subreg:SI (match_dup 1) 0)
4405 (match_dup 2)))
4406
4407 (set (match_dup 3)
4408 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4409 (match_dup 4)))
4410
4411 (set (subreg:SI (match_dup 0) 0)
4412 (ior:SI (subreg:SI (match_dup 0) 0)
4413 (match_dup 3)))
4414
4415 (set (subreg:SI (match_dup 0) 1)
4416 (ashift:SI (subreg:SI (match_dup 1) 1)
4417 (match_dup 2)))]
4418 "
4419 {
4420 int amount = INTVAL (operands[2]);
4421 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4422 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4423 }")
4424
4425
4426 (define_insn "ashldi3_internal4"
4427 [(set (match_operand:DI 0 "register_operand" "=d")
4428 (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
4429 (match_operand:SI 2 "arith_operand" "dI")))]
4430 "TARGET_64BIT"
4431 "*
4432 {
4433 if (GET_CODE (operands[2]) == CONST_INT)
4434 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4435
4436 return \"dsll\\t%0,%1,%2\";
4437 }"
4438 [(set_attr "type" "arith")
4439 (set_attr "mode" "DI")
4440 (set_attr "length" "1")])
4441
4442
4443 (define_insn "ashrsi3"
4444 [(set (match_operand:SI 0 "register_operand" "=d")
4445 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4446 (match_operand:SI 2 "arith_operand" "dI")))]
4447 ""
4448 "*
4449 {
4450 if (GET_CODE (operands[2]) == CONST_INT)
4451 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4452
4453 return \"sra\\t%0,%1,%2\";
4454 }"
4455 [(set_attr "type" "arith")
4456 (set_attr "mode" "SI")
4457 (set_attr "length" "1")])
4458
4459
4460 (define_expand "ashrdi3"
4461 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4462 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
4463 (match_operand:SI 2 "arith_operand" "")))
4464 (clobber (match_dup 3))])]
4465 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4466 "
4467 {
4468 if (TARGET_64BIT)
4469 {
4470 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
4471 operands[2]));
4472 DONE;
4473 }
4474
4475 operands[3] = gen_reg_rtx (SImode);
4476 }")
4477
4478
4479 (define_insn "ashrdi3_internal"
4480 [(set (match_operand:DI 0 "register_operand" "=&d")
4481 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4482 (match_operand:SI 2 "register_operand" "d")))
4483 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4484 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4485 "*
4486 {
4487 operands[4] = const0_rtx;
4488 dslots_jump_total += 3;
4489 dslots_jump_filled += 2;
4490
4491 return \"sll\\t%3,%2,26\\n\\
4492 \\tbgez\\t%3,1f\\n\\
4493 \\tsra\\t%L0,%M1,%2\\n\\
4494 \\t%(b\\t3f\\n\\
4495 \\tsra\\t%M0,%M1,31%)\\n\\
4496 \\n\\
4497 1:\\n\\
4498 \\t%(beq\\t%3,%z4,2f\\n\\
4499 \\tsrl\\t%L0,%L1,%2%)\\n\\
4500 \\n\\
4501 \\tsubu\\t%3,%z4,%2\\n\\
4502 \\tsll\\t%3,%M1,%3\\n\\
4503 \\tor\\t%L0,%L0,%3\\n\\
4504 2:\\n\\
4505 \\tsra\\t%M0,%M1,%2\\n\\
4506 3:\";
4507 }"
4508 [(set_attr "type" "darith")
4509 (set_attr "mode" "DI")
4510 (set_attr "length" "12")])
4511
4512
4513 (define_insn "ashrdi3_internal2"
4514 [(set (match_operand:DI 0 "register_operand" "=d")
4515 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4516 (match_operand:SI 2 "small_int" "IJK")))
4517 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4518 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4519 "*
4520 {
4521 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4522 return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
4523 }"
4524 [(set_attr "type" "darith")
4525 (set_attr "mode" "DI")
4526 (set_attr "length" "2")])
4527
4528
4529 (define_split
4530 [(set (match_operand:DI 0 "register_operand" "")
4531 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4532 (match_operand:SI 2 "small_int" "")))
4533 (clobber (match_operand:SI 3 "register_operand" ""))]
4534 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4535 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4536 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4537 && (INTVAL (operands[2]) & 32) != 0"
4538
4539 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4540 (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
4541
4542 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4543
4544
4545 (define_split
4546 [(set (match_operand:DI 0 "register_operand" "")
4547 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4548 (match_operand:SI 2 "small_int" "")))
4549 (clobber (match_operand:SI 3 "register_operand" ""))]
4550 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4551 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4552 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553 && (INTVAL (operands[2]) & 32) != 0"
4554
4555 [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4556 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
4557
4558 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4559
4560
4561 (define_insn "ashrdi3_internal3"
4562 [(set (match_operand:DI 0 "register_operand" "=d")
4563 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4564 (match_operand:SI 2 "small_int" "IJK")))
4565 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4566 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4567 && (INTVAL (operands[2]) & 63) < 32
4568 && (INTVAL (operands[2]) & 63) != 0"
4569 "*
4570 {
4571 int amount = INTVAL (operands[2]);
4572
4573 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4574 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4575
4576 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
4577 }"
4578 [(set_attr "type" "darith")
4579 (set_attr "mode" "DI")
4580 (set_attr "length" "4")])
4581
4582
4583 (define_split
4584 [(set (match_operand:DI 0 "register_operand" "")
4585 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4586 (match_operand:SI 2 "small_int" "")))
4587 (clobber (match_operand:SI 3 "register_operand" ""))]
4588 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4589 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4590 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4591 && (INTVAL (operands[2]) & 63) < 32
4592 && (INTVAL (operands[2]) & 63) != 0"
4593
4594 [(set (subreg:SI (match_dup 0) 0)
4595 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4596 (match_dup 2)))
4597
4598 (set (match_dup 3)
4599 (ashift:SI (subreg:SI (match_dup 1) 1)
4600 (match_dup 4)))
4601
4602 (set (subreg:SI (match_dup 0) 0)
4603 (ior:SI (subreg:SI (match_dup 0) 0)
4604 (match_dup 3)))
4605
4606 (set (subreg:SI (match_dup 0) 1)
4607 (ashiftrt:SI (subreg:SI (match_dup 1) 1)
4608 (match_dup 2)))]
4609 "
4610 {
4611 int amount = INTVAL (operands[2]);
4612 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4613 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4614 }")
4615
4616
4617 (define_split
4618 [(set (match_operand:DI 0 "register_operand" "")
4619 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4620 (match_operand:SI 2 "small_int" "")))
4621 (clobber (match_operand:SI 3 "register_operand" ""))]
4622 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4623 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4624 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4625 && (INTVAL (operands[2]) & 63) < 32
4626 && (INTVAL (operands[2]) & 63) != 0"
4627
4628 [(set (subreg:SI (match_dup 0) 1)
4629 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4630 (match_dup 2)))
4631
4632 (set (match_dup 3)
4633 (ashift:SI (subreg:SI (match_dup 1) 0)
4634 (match_dup 4)))
4635
4636 (set (subreg:SI (match_dup 0) 1)
4637 (ior:SI (subreg:SI (match_dup 0) 1)
4638 (match_dup 3)))
4639
4640 (set (subreg:SI (match_dup 0) 0)
4641 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
4642 (match_dup 2)))]
4643 "
4644 {
4645 int amount = INTVAL (operands[2]);
4646 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4647 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4648 }")
4649
4650
4651 (define_insn "ashrdi3_internal4"
4652 [(set (match_operand:DI 0 "register_operand" "=d")
4653 (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
4654 (match_operand:SI 2 "arith_operand" "dI")))]
4655 "TARGET_64BIT"
4656 "*
4657 {
4658 if (GET_CODE (operands[2]) == CONST_INT)
4659 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4660
4661 return \"dsra\\t%0,%1,%2\";
4662 }"
4663 [(set_attr "type" "arith")
4664 (set_attr "mode" "DI")
4665 (set_attr "length" "1")])
4666
4667
4668 (define_insn "lshrsi3"
4669 [(set (match_operand:SI 0 "register_operand" "=d")
4670 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4671 (match_operand:SI 2 "arith_operand" "dI")))]
4672 ""
4673 "*
4674 {
4675 if (GET_CODE (operands[2]) == CONST_INT)
4676 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4677
4678 return \"srl\\t%0,%1,%2\";
4679 }"
4680 [(set_attr "type" "arith")
4681 (set_attr "mode" "SI")
4682 (set_attr "length" "1")])
4683
4684
4685 (define_expand "lshrdi3"
4686 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4687 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
4688 (match_operand:SI 2 "arith_operand" "")))
4689 (clobber (match_dup 3))])]
4690 "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4691 "
4692 {
4693 if (TARGET_64BIT)
4694 {
4695 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
4696 operands[2]));
4697 DONE;
4698 }
4699
4700 operands[3] = gen_reg_rtx (SImode);
4701 }")
4702
4703
4704 (define_insn "lshrdi3_internal"
4705 [(set (match_operand:DI 0 "register_operand" "=&d")
4706 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4707 (match_operand:SI 2 "register_operand" "d")))
4708 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4709 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4710 "*
4711 {
4712 operands[4] = const0_rtx;
4713 dslots_jump_total += 3;
4714 dslots_jump_filled += 2;
4715
4716 return \"sll\\t%3,%2,26\\n\\
4717 \\tbgez\\t%3,1f\\n\\
4718 \\tsrl\\t%L0,%M1,%2\\n\\
4719 \\t%(b\\t3f\\n\\
4720 \\tmove\\t%M0,%z4%)\\n\\
4721 \\n\\
4722 1:\\n\\
4723 \\t%(beq\\t%3,%z4,2f\\n\\
4724 \\tsrl\\t%L0,%L1,%2%)\\n\\
4725 \\n\\
4726 \\tsubu\\t%3,%z4,%2\\n\\
4727 \\tsll\\t%3,%M1,%3\\n\\
4728 \\tor\\t%L0,%L0,%3\\n\\
4729 2:\\n\\
4730 \\tsrl\\t%M0,%M1,%2\\n\\
4731 3:\";
4732 }"
4733 [(set_attr "type" "darith")
4734 (set_attr "mode" "DI")
4735 (set_attr "length" "12")])
4736
4737
4738 (define_insn "lshrdi3_internal2"
4739 [(set (match_operand:DI 0 "register_operand" "=d")
4740 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4741 (match_operand:SI 2 "small_int" "IJK")))
4742 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4743 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4744 "*
4745 {
4746 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4747 operands[4] = const0_rtx;
4748 return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
4749 }"
4750 [(set_attr "type" "darith")
4751 (set_attr "mode" "DI")
4752 (set_attr "length" "2")])
4753
4754
4755 (define_split
4756 [(set (match_operand:DI 0 "register_operand" "")
4757 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4758 (match_operand:SI 2 "small_int" "")))
4759 (clobber (match_operand:SI 3 "register_operand" ""))]
4760 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4761 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4762 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4763 && (INTVAL (operands[2]) & 32) != 0"
4764
4765 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4766 (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4767
4768 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4769
4770
4771 (define_split
4772 [(set (match_operand:DI 0 "register_operand" "")
4773 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4774 (match_operand:SI 2 "small_int" "")))
4775 (clobber (match_operand:SI 3 "register_operand" ""))]
4776 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4777 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4778 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4779 && (INTVAL (operands[2]) & 32) != 0"
4780
4781 [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4782 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4783
4784 "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4785
4786
4787 (define_insn "lshrdi3_internal3"
4788 [(set (match_operand:DI 0 "register_operand" "=d")
4789 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4790 (match_operand:SI 2 "small_int" "IJK")))
4791 (clobber (match_operand:SI 3 "register_operand" "=d"))]
4792 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4793 && (INTVAL (operands[2]) & 63) < 32
4794 && (INTVAL (operands[2]) & 63) != 0"
4795 "*
4796 {
4797 int amount = INTVAL (operands[2]);
4798
4799 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4800 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4801
4802 return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
4803 }"
4804 [(set_attr "type" "darith")
4805 (set_attr "mode" "DI")
4806 (set_attr "length" "4")])
4807
4808
4809 (define_split
4810 [(set (match_operand:DI 0 "register_operand" "")
4811 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4812 (match_operand:SI 2 "small_int" "")))
4813 (clobber (match_operand:SI 3 "register_operand" ""))]
4814 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4815 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4816 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4817 && (INTVAL (operands[2]) & 63) < 32
4818 && (INTVAL (operands[2]) & 63) != 0"
4819
4820 [(set (subreg:SI (match_dup 0) 0)
4821 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4822 (match_dup 2)))
4823
4824 (set (match_dup 3)
4825 (ashift:SI (subreg:SI (match_dup 1) 1)
4826 (match_dup 4)))
4827
4828 (set (subreg:SI (match_dup 0) 0)
4829 (ior:SI (subreg:SI (match_dup 0) 0)
4830 (match_dup 3)))
4831
4832 (set (subreg:SI (match_dup 0) 1)
4833 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4834 (match_dup 2)))]
4835 "
4836 {
4837 int amount = INTVAL (operands[2]);
4838 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4839 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4840 }")
4841
4842
4843 (define_split
4844 [(set (match_operand:DI 0 "register_operand" "")
4845 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4846 (match_operand:SI 2 "small_int" "")))
4847 (clobber (match_operand:SI 3 "register_operand" ""))]
4848 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4849 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4850 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4851 && (INTVAL (operands[2]) & 63) < 32
4852 && (INTVAL (operands[2]) & 63) != 0"
4853
4854 [(set (subreg:SI (match_dup 0) 1)
4855 (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4856 (match_dup 2)))
4857
4858 (set (match_dup 3)
4859 (ashift:SI (subreg:SI (match_dup 1) 0)
4860 (match_dup 4)))
4861
4862 (set (subreg:SI (match_dup 0) 1)
4863 (ior:SI (subreg:SI (match_dup 0) 1)
4864 (match_dup 3)))
4865
4866 (set (subreg:SI (match_dup 0) 0)
4867 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4868 (match_dup 2)))]
4869 "
4870 {
4871 int amount = INTVAL (operands[2]);
4872 operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4873 operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4874 }")
4875
4876
4877 (define_insn "lshrdi3_internal4"
4878 [(set (match_operand:DI 0 "register_operand" "=d")
4879 (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
4880 (match_operand:SI 2 "arith_operand" "dI")))]
4881 "TARGET_64BIT"
4882 "*
4883 {
4884 if (GET_CODE (operands[2]) == CONST_INT)
4885 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4886
4887 return \"dsrl\\t%0,%1,%2\";
4888 }"
4889 [(set_attr "type" "arith")
4890 (set_attr "mode" "DI")
4891 (set_attr "length" "1")])
4892
4893 \f
4894 ;;
4895 ;; ....................
4896 ;;
4897 ;; COMPARISONS
4898 ;;
4899 ;; ....................
4900
4901 ;; Flow here is rather complex:
4902 ;;
4903 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
4904 ;; arguments into the branch_cmp array, and the type into
4905 ;; branch_type. No RTL is generated.
4906 ;;
4907 ;; 2) The appropriate branch define_expand is called, which then
4908 ;; creates the appropriate RTL for the comparison and branch.
4909 ;; Different CC modes are used, based on what type of branch is
4910 ;; done, so that we can constrain things appropriately. There
4911 ;; are assumptions in the rest of GCC that break if we fold the
4912 ;; operands into the branchs for integer operations, and use cc0
4913 ;; for floating point, so we use the fp status register instead.
4914 ;; If needed, an appropriate temporary is created to hold the
4915 ;; of the integer compare.
4916
4917 (define_expand "cmpsi"
4918 [(set (cc0)
4919 (compare:CC (match_operand:SI 0 "register_operand" "")
4920 (match_operand:SI 1 "arith_operand" "")))]
4921 ""
4922 "
4923 {
4924 if (operands[0]) /* avoid unused code message */
4925 {
4926 branch_cmp[0] = operands[0];
4927 branch_cmp[1] = operands[1];
4928 branch_type = CMP_SI;
4929 DONE;
4930 }
4931 }")
4932
4933 (define_expand "tstsi"
4934 [(set (cc0)
4935 (match_operand:SI 0 "register_operand" ""))]
4936 ""
4937 "
4938 {
4939 if (operands[0]) /* avoid unused code message */
4940 {
4941 branch_cmp[0] = operands[0];
4942 branch_cmp[1] = const0_rtx;
4943 branch_type = CMP_SI;
4944 DONE;
4945 }
4946 }")
4947
4948 (define_expand "cmpdi"
4949 [(set (cc0)
4950 (compare:CC (match_operand:DI 0 "se_register_operand" "")
4951 (match_operand:DI 1 "se_arith_operand" "")))]
4952 "TARGET_64BIT"
4953 "
4954 {
4955 if (operands[0]) /* avoid unused code message */
4956 {
4957 branch_cmp[0] = operands[0];
4958 branch_cmp[1] = operands[1];
4959 branch_type = CMP_DI;
4960 DONE;
4961 }
4962 }")
4963
4964 (define_expand "tstdi"
4965 [(set (cc0)
4966 (match_operand:DI 0 "se_register_operand" ""))]
4967 "TARGET_64BIT"
4968 "
4969 {
4970 if (operands[0]) /* avoid unused code message */
4971 {
4972 branch_cmp[0] = operands[0];
4973 branch_cmp[1] = const0_rtx;
4974 branch_type = CMP_DI;
4975 DONE;
4976 }
4977 }")
4978
4979 (define_expand "cmpdf"
4980 [(set (cc0)
4981 (compare:CC (match_operand:DF 0 "register_operand" "")
4982 (match_operand:DF 1 "register_operand" "")))]
4983 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4984 "
4985 {
4986 if (operands[0]) /* avoid unused code message */
4987 {
4988 branch_cmp[0] = operands[0];
4989 branch_cmp[1] = operands[1];
4990 branch_type = CMP_DF;
4991 DONE;
4992 }
4993 }")
4994
4995 (define_expand "cmpsf"
4996 [(set (cc0)
4997 (compare:CC (match_operand:SF 0 "register_operand" "")
4998 (match_operand:SF 1 "register_operand" "")))]
4999 "TARGET_HARD_FLOAT"
5000 "
5001 {
5002 if (operands[0]) /* avoid unused code message */
5003 {
5004 branch_cmp[0] = operands[0];
5005 branch_cmp[1] = operands[1];
5006 branch_type = CMP_SF;
5007 DONE;
5008 }
5009 }")
5010
5011 \f
5012 ;;
5013 ;; ....................
5014 ;;
5015 ;; CONDITIONAL BRANCHES
5016 ;;
5017 ;; ....................
5018
5019 (define_insn "branch_fp_ne"
5020 [(set (pc)
5021 (if_then_else (ne:CC (match_operand:CC 0 "register_operand" "z")
5022 (const_int 0))
5023 (match_operand 1 "pc_or_label_operand" "")
5024 (match_operand 2 "pc_or_label_operand" "")))]
5025 "TARGET_HARD_FLOAT"
5026 "*
5027 {
5028 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5029 return (operands[1] != pc_rtx) ? \"%*bc1t%?\\t%Z0%1\" : \"%*bc1f%?\\t%Z0%2\";
5030 }"
5031 [(set_attr "type" "branch")
5032 (set_attr "mode" "none")
5033 (set_attr "length" "1")])
5034
5035 (define_insn "branch_fp_eq"
5036 [(set (pc)
5037 (if_then_else (eq:CC (match_operand:CC 0 "register_operand" "z")
5038 (const_int 0))
5039 (match_operand 1 "pc_or_label_operand" "")
5040 (match_operand 2 "pc_or_label_operand" "")))]
5041 "TARGET_HARD_FLOAT"
5042 "*
5043 {
5044 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5045 return (operands[1] != pc_rtx) ? \"%*bc1f%?\\t%Z0%1\" : \"%*bc1t%?\\t%Z0%2\";
5046 }"
5047 [(set_attr "type" "branch")
5048 (set_attr "mode" "none")
5049 (set_attr "length" "1")])
5050
5051 (define_insn "branch_zero"
5052 [(set (pc)
5053 (if_then_else (match_operator:SI 0 "cmp_op"
5054 [(match_operand:SI 1 "register_operand" "d")
5055 (const_int 0)])
5056 (match_operand 2 "pc_or_label_operand" "")
5057 (match_operand 3 "pc_or_label_operand" "")))]
5058 ""
5059 "*
5060 {
5061 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5062 if (operands[2] != pc_rtx)
5063 { /* normal jump */
5064 switch (GET_CODE (operands[0]))
5065 {
5066 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
5067 case NE: return \"%*bne%?\\t%z1,%.,%2\";
5068 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
5069 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
5070 case GEU: return \"%*j\\t%2\";
5071 case LTU: return \"%*bne%?\\t%.,%.,%2\";
5072 }
5073
5074 return \"%*b%C0z%?\\t%z1,%2\";
5075 }
5076 else
5077 { /* inverted jump */
5078 switch (GET_CODE (operands[0]))
5079 {
5080 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
5081 case NE: return \"%*beq%?\\t%z1,%.,%3\";
5082 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
5083 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
5084 case GEU: return \"%*beq%?\\t%.,%.,%3\";
5085 case LTU: return \"%*j\\t%3\";
5086 }
5087
5088 return \"%*b%N0z%?\\t%z1,%3\";
5089 }
5090 }"
5091 [(set_attr "type" "branch")
5092 (set_attr "mode" "none")
5093 (set_attr "length" "1")])
5094
5095
5096 (define_insn "branch_zero_di"
5097 [(set (pc)
5098 (if_then_else (match_operator:DI 0 "cmp_op"
5099 [(match_operand:DI 1 "se_register_operand" "d")
5100 (const_int 0)])
5101 (match_operand 2 "pc_or_label_operand" "")
5102 (match_operand 3 "pc_or_label_operand" "")))]
5103 ""
5104 "*
5105 {
5106 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5107 if (operands[2] != pc_rtx)
5108 { /* normal jump */
5109 switch (GET_CODE (operands[0]))
5110 {
5111 case EQ: return \"%*beq%?\\t%z1,%.,%2\";
5112 case NE: return \"%*bne%?\\t%z1,%.,%2\";
5113 case GTU: return \"%*bne%?\\t%z1,%.,%2\";
5114 case LEU: return \"%*beq%?\\t%z1,%.,%2\";
5115 case GEU: return \"%*j\\t%2\";
5116 case LTU: return \"%*bne%?\\t%.,%.,%2\";
5117 }
5118
5119 return \"%*b%C0z%?\\t%z1,%2\";
5120 }
5121 else
5122 { /* inverted jump */
5123 switch (GET_CODE (operands[0]))
5124 {
5125 case EQ: return \"%*bne%?\\t%z1,%.,%3\";
5126 case NE: return \"%*beq%?\\t%z1,%.,%3\";
5127 case GTU: return \"%*beq%?\\t%z1,%.,%3\";
5128 case LEU: return \"%*bne%?\\t%z1,%.,%3\";
5129 case GEU: return \"%*beq%?\\t%.,%.,%3\";
5130 case LTU: return \"%*j\\t%3\";
5131 }
5132
5133 return \"%*b%N0z%?\\t%z1,%3\";
5134 }
5135 }"
5136 [(set_attr "type" "branch")
5137 (set_attr "mode" "none")
5138 (set_attr "length" "1")])
5139
5140
5141 (define_insn "branch_equality"
5142 [(set (pc)
5143 (if_then_else (match_operator:SI 0 "equality_op"
5144 [(match_operand:SI 1 "register_operand" "d")
5145 (match_operand:SI 2 "register_operand" "d")])
5146 (match_operand 3 "pc_or_label_operand" "")
5147 (match_operand 4 "pc_or_label_operand" "")))]
5148 ""
5149 "*
5150 {
5151 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5152 return (operands[3] != pc_rtx)
5153 ? \"%*b%C0%?\\t%z1,%z2,%3\"
5154 : \"%*b%N0%?\\t%z1,%z2,%4\";
5155 }"
5156 [(set_attr "type" "branch")
5157 (set_attr "mode" "none")
5158 (set_attr "length" "1")])
5159
5160
5161 (define_insn "branch_equality_di"
5162 [(set (pc)
5163 (if_then_else (match_operator:DI 0 "equality_op"
5164 [(match_operand:DI 1 "se_register_operand" "d")
5165 (match_operand:DI 2 "se_register_operand" "d")])
5166 (match_operand 3 "pc_or_label_operand" "")
5167 (match_operand 4 "pc_or_label_operand" "")))]
5168 ""
5169 "*
5170 {
5171 mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5172 return (operands[3] != pc_rtx)
5173 ? \"%*b%C0%?\\t%z1,%z2,%3\"
5174 : \"%*b%N0%?\\t%z1,%z2,%4\";
5175 }"
5176 [(set_attr "type" "branch")
5177 (set_attr "mode" "none")
5178 (set_attr "length" "1")])
5179
5180
5181 (define_expand "beq"
5182 [(set (pc)
5183 (if_then_else (eq:CC (cc0)
5184 (const_int 0))
5185 (label_ref (match_operand 0 "" ""))
5186 (pc)))]
5187 ""
5188 "
5189 {
5190 if (operands[0]) /* avoid unused code warning */
5191 {
5192 gen_conditional_branch (operands, EQ);
5193 DONE;
5194 }
5195 }")
5196
5197 (define_expand "bne"
5198 [(set (pc)
5199 (if_then_else (ne:CC (cc0)
5200 (const_int 0))
5201 (label_ref (match_operand 0 "" ""))
5202 (pc)))]
5203 ""
5204 "
5205 {
5206 if (operands[0]) /* avoid unused code warning */
5207 {
5208 gen_conditional_branch (operands, NE);
5209 DONE;
5210 }
5211 }")
5212
5213 (define_expand "bgt"
5214 [(set (pc)
5215 (if_then_else (gt:CC (cc0)
5216 (const_int 0))
5217 (label_ref (match_operand 0 "" ""))
5218 (pc)))]
5219 ""
5220 "
5221 {
5222 if (operands[0]) /* avoid unused code warning */
5223 {
5224 gen_conditional_branch (operands, GT);
5225 DONE;
5226 }
5227 }")
5228
5229 (define_expand "bge"
5230 [(set (pc)
5231 (if_then_else (ge:CC (cc0)
5232 (const_int 0))
5233 (label_ref (match_operand 0 "" ""))
5234 (pc)))]
5235 ""
5236 "
5237 {
5238 if (operands[0]) /* avoid unused code warning */
5239 {
5240 gen_conditional_branch (operands, GE);
5241 DONE;
5242 }
5243 }")
5244
5245 (define_expand "blt"
5246 [(set (pc)
5247 (if_then_else (lt:CC (cc0)
5248 (const_int 0))
5249 (label_ref (match_operand 0 "" ""))
5250 (pc)))]
5251 ""
5252 "
5253 {
5254 if (operands[0]) /* avoid unused code warning */
5255 {
5256 gen_conditional_branch (operands, LT);
5257 DONE;
5258 }
5259 }")
5260
5261 (define_expand "ble"
5262 [(set (pc)
5263 (if_then_else (le:CC (cc0)
5264 (const_int 0))
5265 (label_ref (match_operand 0 "" ""))
5266 (pc)))]
5267 ""
5268 "
5269 {
5270 if (operands[0]) /* avoid unused code warning */
5271 {
5272 gen_conditional_branch (operands, LE);
5273 DONE;
5274 }
5275 }")
5276
5277 (define_expand "bgtu"
5278 [(set (pc)
5279 (if_then_else (gtu:CC (cc0)
5280 (const_int 0))
5281 (label_ref (match_operand 0 "" ""))
5282 (pc)))]
5283 ""
5284 "
5285 {
5286 if (operands[0]) /* avoid unused code warning */
5287 {
5288 gen_conditional_branch (operands, GTU);
5289 DONE;
5290 }
5291 }")
5292
5293 (define_expand "bgeu"
5294 [(set (pc)
5295 (if_then_else (geu:CC (cc0)
5296 (const_int 0))
5297 (label_ref (match_operand 0 "" ""))
5298 (pc)))]
5299 ""
5300 "
5301 {
5302 if (operands[0]) /* avoid unused code warning */
5303 {
5304 gen_conditional_branch (operands, GEU);
5305 DONE;
5306 }
5307 }")
5308
5309
5310 (define_expand "bltu"
5311 [(set (pc)
5312 (if_then_else (ltu:CC (cc0)
5313 (const_int 0))
5314 (label_ref (match_operand 0 "" ""))
5315 (pc)))]
5316 ""
5317 "
5318 {
5319 if (operands[0]) /* avoid unused code warning */
5320 {
5321 gen_conditional_branch (operands, LTU);
5322 DONE;
5323 }
5324 }")
5325
5326 (define_expand "bleu"
5327 [(set (pc)
5328 (if_then_else (leu:CC (cc0)
5329 (const_int 0))
5330 (label_ref (match_operand 0 "" ""))
5331 (pc)))]
5332 ""
5333 "
5334 {
5335 if (operands[0]) /* avoid unused code warning */
5336 {
5337 gen_conditional_branch (operands, LEU);
5338 DONE;
5339 }
5340 }")
5341
5342 \f
5343 ;;
5344 ;; ....................
5345 ;;
5346 ;; SETTING A REGISTER FROM A COMPARISON
5347 ;;
5348 ;; ....................
5349
5350 (define_expand "seq"
5351 [(set (match_operand:SI 0 "register_operand" "=d")
5352 (eq:SI (match_dup 1)
5353 (match_dup 2)))]
5354 ""
5355 "
5356 {
5357 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5358 FAIL;
5359
5360 /* set up operands from compare. */
5361 operands[1] = branch_cmp[0];
5362 operands[2] = branch_cmp[1];
5363
5364 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5365 {
5366 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
5367 DONE;
5368 }
5369
5370 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
5371 operands[2] = force_reg (SImode, operands[2]);
5372
5373 /* fall through and generate default code */
5374 }")
5375
5376
5377 (define_insn "seq_si_zero"
5378 [(set (match_operand:SI 0 "register_operand" "=d")
5379 (eq:SI (match_operand:SI 1 "register_operand" "d")
5380 (const_int 0)))]
5381 ""
5382 "sltu\\t%0,%1,1"
5383 [(set_attr "type" "arith")
5384 (set_attr "mode" "SI")
5385 (set_attr "length" "1")])
5386
5387 (define_insn "seq_di_zero"
5388 [(set (match_operand:DI 0 "register_operand" "=d")
5389 (eq:DI (match_operand:DI 1 "se_register_operand" "d")
5390 (const_int 0)))]
5391 "TARGET_64BIT"
5392 "sltu\\t%0,%1,1"
5393 [(set_attr "type" "arith")
5394 (set_attr "mode" "DI")
5395 (set_attr "length" "1")])
5396
5397 (define_insn "seq_si"
5398 [(set (match_operand:SI 0 "register_operand" "=d,d")
5399 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
5400 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5401 "TARGET_DEBUG_C_MODE"
5402 "@
5403 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
5404 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
5405 [(set_attr "type" "arith")
5406 (set_attr "mode" "SI")
5407 (set_attr "length" "2")])
5408
5409 (define_split
5410 [(set (match_operand:SI 0 "register_operand" "")
5411 (eq:SI (match_operand:SI 1 "register_operand" "")
5412 (match_operand:SI 2 "uns_arith_operand" "")))]
5413 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5414 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5415 [(set (match_dup 0)
5416 (xor:SI (match_dup 1)
5417 (match_dup 2)))
5418 (set (match_dup 0)
5419 (ltu:SI (match_dup 0)
5420 (const_int 1)))]
5421 "")
5422
5423 (define_insn "seq_di"
5424 [(set (match_operand:DI 0 "register_operand" "=d,d")
5425 (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
5426 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
5427 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5428 "@
5429 xor\\t%0,%1,%2\;sltu\\t%0,%0,1
5430 xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
5431 [(set_attr "type" "arith")
5432 (set_attr "mode" "DI")
5433 (set_attr "length" "2")])
5434
5435 (define_split
5436 [(set (match_operand:DI 0 "register_operand" "")
5437 (eq:DI (match_operand:DI 1 "se_register_operand" "")
5438 (match_operand:DI 2 "se_uns_arith_operand" "")))]
5439 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5440 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5441 [(set (match_dup 0)
5442 (xor:DI (match_dup 1)
5443 (match_dup 2)))
5444 (set (match_dup 0)
5445 (ltu:DI (match_dup 0)
5446 (const_int 1)))]
5447 "")
5448
5449 (define_expand "sne"
5450 [(set (match_operand:SI 0 "register_operand" "=d")
5451 (ne:SI (match_dup 1)
5452 (match_dup 2)))]
5453 ""
5454 "
5455 {
5456 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5457 FAIL;
5458
5459 /* set up operands from compare. */
5460 operands[1] = branch_cmp[0];
5461 operands[2] = branch_cmp[1];
5462
5463 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5464 {
5465 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
5466 DONE;
5467 }
5468
5469 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
5470 operands[2] = force_reg (SImode, operands[2]);
5471
5472 /* fall through and generate default code */
5473 }")
5474
5475 (define_insn "sne_si_zero"
5476 [(set (match_operand:SI 0 "register_operand" "=d")
5477 (ne:SI (match_operand:SI 1 "register_operand" "d")
5478 (const_int 0)))]
5479 ""
5480 "sltu\\t%0,%.,%1"
5481 [(set_attr "type" "arith")
5482 (set_attr "mode" "SI")
5483 (set_attr "length" "1")])
5484
5485 (define_insn "sne_di_zero"
5486 [(set (match_operand:DI 0 "register_operand" "=d")
5487 (ne:DI (match_operand:DI 1 "se_register_operand" "d")
5488 (const_int 0)))]
5489 "TARGET_64BIT"
5490 "sltu\\t%0,%.,%1"
5491 [(set_attr "type" "arith")
5492 (set_attr "mode" "DI")
5493 (set_attr "length" "1")])
5494
5495 (define_insn "sne_si"
5496 [(set (match_operand:SI 0 "register_operand" "=d,d")
5497 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
5498 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5499 "TARGET_DEBUG_C_MODE"
5500 "@
5501 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5502 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5503 [(set_attr "type" "arith")
5504 (set_attr "mode" "SI")
5505 (set_attr "length" "2")])
5506
5507 (define_split
5508 [(set (match_operand:SI 0 "register_operand" "")
5509 (ne:SI (match_operand:SI 1 "register_operand" "")
5510 (match_operand:SI 2 "uns_arith_operand" "")))]
5511 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5512 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5513 [(set (match_dup 0)
5514 (xor:SI (match_dup 1)
5515 (match_dup 2)))
5516 (set (match_dup 0)
5517 (gtu:SI (match_dup 0)
5518 (const_int 0)))]
5519 "")
5520
5521 (define_insn "sne_di"
5522 [(set (match_operand:DI 0 "register_operand" "=d,d")
5523 (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
5524 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
5525 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5526 "@
5527 xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5528 xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5529 [(set_attr "type" "arith")
5530 (set_attr "mode" "DI")
5531 (set_attr "length" "2")])
5532
5533 (define_split
5534 [(set (match_operand:DI 0 "register_operand" "")
5535 (ne:DI (match_operand:DI 1 "se_register_operand" "")
5536 (match_operand:DI 2 "se_uns_arith_operand" "")))]
5537 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5538 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5539 [(set (match_dup 0)
5540 (xor:DI (match_dup 1)
5541 (match_dup 2)))
5542 (set (match_dup 0)
5543 (gtu:DI (match_dup 0)
5544 (const_int 0)))]
5545 "")
5546
5547 (define_expand "sgt"
5548 [(set (match_operand:SI 0 "register_operand" "=d")
5549 (gt:SI (match_dup 1)
5550 (match_dup 2)))]
5551 ""
5552 "
5553 {
5554 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5555 FAIL;
5556
5557 /* set up operands from compare. */
5558 operands[1] = branch_cmp[0];
5559 operands[2] = branch_cmp[1];
5560
5561 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5562 {
5563 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
5564 DONE;
5565 }
5566
5567 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5568 operands[2] = force_reg (SImode, operands[2]);
5569
5570 /* fall through and generate default code */
5571 }")
5572
5573 (define_insn "sgt_si"
5574 [(set (match_operand:SI 0 "register_operand" "=d")
5575 (gt:SI (match_operand:SI 1 "register_operand" "d")
5576 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5577 ""
5578 "slt\\t%0,%z2,%1"
5579 [(set_attr "type" "arith")
5580 (set_attr "mode" "SI")
5581 (set_attr "length" "1")])
5582
5583 (define_insn "sgt_di"
5584 [(set (match_operand:DI 0 "register_operand" "=d")
5585 (gt:DI (match_operand:DI 1 "se_register_operand" "d")
5586 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
5587 "TARGET_64BIT"
5588 "slt\\t%0,%z2,%1"
5589 [(set_attr "type" "arith")
5590 (set_attr "mode" "DI")
5591 (set_attr "length" "1")])
5592
5593 (define_expand "sge"
5594 [(set (match_operand:SI 0 "register_operand" "=d")
5595 (ge:SI (match_dup 1)
5596 (match_dup 2)))]
5597 ""
5598 "
5599 {
5600 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5601 FAIL;
5602
5603 /* set up operands from compare. */
5604 operands[1] = branch_cmp[0];
5605 operands[2] = branch_cmp[1];
5606
5607 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5608 {
5609 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
5610 DONE;
5611 }
5612
5613 /* fall through and generate default code */
5614 }")
5615
5616 (define_insn "sge_si"
5617 [(set (match_operand:SI 0 "register_operand" "=d")
5618 (ge:SI (match_operand:SI 1 "register_operand" "d")
5619 (match_operand:SI 2 "arith_operand" "dI")))]
5620 "TARGET_DEBUG_C_MODE"
5621 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5622 [(set_attr "type" "arith")
5623 (set_attr "mode" "SI")
5624 (set_attr "length" "2")])
5625
5626 (define_split
5627 [(set (match_operand:SI 0 "register_operand" "")
5628 (ge:SI (match_operand:SI 1 "register_operand" "")
5629 (match_operand:SI 2 "arith_operand" "")))]
5630 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5631 [(set (match_dup 0)
5632 (lt:SI (match_dup 1)
5633 (match_dup 2)))
5634 (set (match_dup 0)
5635 (xor:SI (match_dup 0)
5636 (const_int 1)))]
5637 "")
5638
5639 (define_insn "sge_di"
5640 [(set (match_operand:DI 0 "register_operand" "=d")
5641 (ge:DI (match_operand:DI 1 "se_register_operand" "d")
5642 (match_operand:DI 2 "se_arith_operand" "dI")))]
5643 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5644 "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5645 [(set_attr "type" "arith")
5646 (set_attr "mode" "DI")
5647 (set_attr "length" "2")])
5648
5649 (define_split
5650 [(set (match_operand:DI 0 "register_operand" "")
5651 (ge:DI (match_operand:DI 1 "se_register_operand" "")
5652 (match_operand:DI 2 "se_arith_operand" "")))]
5653 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5654 [(set (match_dup 0)
5655 (lt:DI (match_dup 1)
5656 (match_dup 2)))
5657 (set (match_dup 0)
5658 (xor:DI (match_dup 0)
5659 (const_int 1)))]
5660 "")
5661
5662 (define_expand "slt"
5663 [(set (match_operand:SI 0 "register_operand" "=d")
5664 (lt:SI (match_dup 1)
5665 (match_dup 2)))]
5666 ""
5667 "
5668 {
5669 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5670 FAIL;
5671
5672 /* set up operands from compare. */
5673 operands[1] = branch_cmp[0];
5674 operands[2] = branch_cmp[1];
5675
5676 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5677 {
5678 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
5679 DONE;
5680 }
5681
5682 /* fall through and generate default code */
5683 }")
5684
5685 (define_insn "slt_si"
5686 [(set (match_operand:SI 0 "register_operand" "=d")
5687 (lt:SI (match_operand:SI 1 "register_operand" "d")
5688 (match_operand:SI 2 "arith_operand" "dI")))]
5689 ""
5690 "slt\\t%0,%1,%2"
5691 [(set_attr "type" "arith")
5692 (set_attr "mode" "SI")
5693 (set_attr "length" "1")])
5694
5695 (define_insn "slt_di"
5696 [(set (match_operand:DI 0 "register_operand" "=d")
5697 (lt:DI (match_operand:DI 1 "se_register_operand" "d")
5698 (match_operand:DI 2 "se_arith_operand" "dI")))]
5699 "TARGET_64BIT"
5700 "slt\\t%0,%1,%2"
5701 [(set_attr "type" "arith")
5702 (set_attr "mode" "DI")
5703 (set_attr "length" "1")])
5704
5705 (define_expand "sle"
5706 [(set (match_operand:SI 0 "register_operand" "=d")
5707 (le:SI (match_dup 1)
5708 (match_dup 2)))]
5709 ""
5710 "
5711 {
5712 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5713 FAIL;
5714
5715 /* set up operands from compare. */
5716 operands[1] = branch_cmp[0];
5717 operands[2] = branch_cmp[1];
5718
5719 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5720 {
5721 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
5722 DONE;
5723 }
5724
5725 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5726 operands[2] = force_reg (SImode, operands[2]);
5727
5728 /* fall through and generate default code */
5729 }")
5730
5731 (define_insn "sle_si_const"
5732 [(set (match_operand:SI 0 "register_operand" "=d")
5733 (le:SI (match_operand:SI 1 "register_operand" "d")
5734 (match_operand:SI 2 "small_int" "I")))]
5735 "INTVAL (operands[2]) < 32767"
5736 "*
5737 {
5738 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5739 return \"slt\\t%0,%1,%2\";
5740 }"
5741 [(set_attr "type" "arith")
5742 (set_attr "mode" "SI")
5743 (set_attr "length" "1")])
5744
5745 (define_insn "sle_di_const"
5746 [(set (match_operand:DI 0 "register_operand" "=d")
5747 (le:DI (match_operand:DI 1 "se_register_operand" "d")
5748 (match_operand:DI 2 "small_int" "I")))]
5749 "TARGET_64BIT && INTVAL (operands[2]) < 32767"
5750 "*
5751 {
5752 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5753 return \"slt\\t%0,%1,%2\";
5754 }"
5755 [(set_attr "type" "arith")
5756 (set_attr "mode" "DI")
5757 (set_attr "length" "1")])
5758
5759 (define_insn "sle_si_reg"
5760 [(set (match_operand:SI 0 "register_operand" "=d")
5761 (le:SI (match_operand:SI 1 "register_operand" "d")
5762 (match_operand:SI 2 "register_operand" "d")))]
5763 "TARGET_DEBUG_C_MODE"
5764 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5765 [(set_attr "type" "arith")
5766 (set_attr "mode" "SI")
5767 (set_attr "length" "2")])
5768
5769 (define_split
5770 [(set (match_operand:SI 0 "register_operand" "")
5771 (le:SI (match_operand:SI 1 "register_operand" "")
5772 (match_operand:SI 2 "register_operand" "")))]
5773 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5774 [(set (match_dup 0)
5775 (lt:SI (match_dup 2)
5776 (match_dup 1)))
5777 (set (match_dup 0)
5778 (xor:SI (match_dup 0)
5779 (const_int 1)))]
5780 "")
5781
5782 (define_insn "sle_di_reg"
5783 [(set (match_operand:DI 0 "register_operand" "=d")
5784 (le:DI (match_operand:DI 1 "se_register_operand" "d")
5785 (match_operand:DI 2 "se_register_operand" "d")))]
5786 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5787 "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5788 [(set_attr "type" "arith")
5789 (set_attr "mode" "DI")
5790 (set_attr "length" "2")])
5791
5792 (define_split
5793 [(set (match_operand:DI 0 "register_operand" "")
5794 (le:DI (match_operand:DI 1 "se_register_operand" "")
5795 (match_operand:DI 2 "se_register_operand" "")))]
5796 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5797 [(set (match_dup 0)
5798 (lt:DI (match_dup 2)
5799 (match_dup 1)))
5800 (set (match_dup 0)
5801 (xor:DI (match_dup 0)
5802 (const_int 1)))]
5803 "")
5804
5805 (define_expand "sgtu"
5806 [(set (match_operand:SI 0 "register_operand" "=d")
5807 (gtu:SI (match_dup 1)
5808 (match_dup 2)))]
5809 ""
5810 "
5811 {
5812 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5813 FAIL;
5814
5815 /* set up operands from compare. */
5816 operands[1] = branch_cmp[0];
5817 operands[2] = branch_cmp[1];
5818
5819 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5820 {
5821 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
5822 DONE;
5823 }
5824
5825 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5826 operands[2] = force_reg (SImode, operands[2]);
5827
5828 /* fall through and generate default code */
5829 }")
5830
5831 (define_insn "sgtu_si"
5832 [(set (match_operand:SI 0 "register_operand" "=d")
5833 (gtu:SI (match_operand:SI 1 "register_operand" "d")
5834 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5835 ""
5836 "sltu\\t%0,%z2,%1"
5837 [(set_attr "type" "arith")
5838 (set_attr "mode" "SI")
5839 (set_attr "length" "1")])
5840
5841 (define_insn "sgtu_di"
5842 [(set (match_operand:DI 0 "register_operand" "=d")
5843 (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
5844 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
5845 "TARGET_64BIT"
5846 "sltu\\t%0,%z2,%1"
5847 [(set_attr "type" "arith")
5848 (set_attr "mode" "DI")
5849 (set_attr "length" "1")])
5850
5851 (define_expand "sgeu"
5852 [(set (match_operand:SI 0 "register_operand" "=d")
5853 (geu:SI (match_dup 1)
5854 (match_dup 2)))]
5855 ""
5856 "
5857 {
5858 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5859 FAIL;
5860
5861 /* set up operands from compare. */
5862 operands[1] = branch_cmp[0];
5863 operands[2] = branch_cmp[1];
5864
5865 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5866 {
5867 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
5868 DONE;
5869 }
5870
5871 /* fall through and generate default code */
5872 }")
5873
5874 (define_insn "sgeu_si"
5875 [(set (match_operand:SI 0 "register_operand" "=d")
5876 (geu:SI (match_operand:SI 1 "register_operand" "d")
5877 (match_operand:SI 2 "arith_operand" "dI")))]
5878 "TARGET_DEBUG_C_MODE"
5879 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5880 [(set_attr "type" "arith")
5881 (set_attr "mode" "SI")
5882 (set_attr "length" "2")])
5883
5884 (define_split
5885 [(set (match_operand:SI 0 "register_operand" "")
5886 (geu:SI (match_operand:SI 1 "register_operand" "")
5887 (match_operand:SI 2 "arith_operand" "")))]
5888 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5889 [(set (match_dup 0)
5890 (ltu:SI (match_dup 1)
5891 (match_dup 2)))
5892 (set (match_dup 0)
5893 (xor:SI (match_dup 0)
5894 (const_int 1)))]
5895 "")
5896
5897 (define_insn "sgeu_di"
5898 [(set (match_operand:DI 0 "register_operand" "=d")
5899 (geu:DI (match_operand:DI 1 "se_register_operand" "d")
5900 (match_operand:DI 2 "se_arith_operand" "dI")))]
5901 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5902 "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5903 [(set_attr "type" "arith")
5904 (set_attr "mode" "DI")
5905 (set_attr "length" "2")])
5906
5907 (define_split
5908 [(set (match_operand:DI 0 "register_operand" "")
5909 (geu:DI (match_operand:DI 1 "se_register_operand" "")
5910 (match_operand:DI 2 "se_arith_operand" "")))]
5911 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5912 [(set (match_dup 0)
5913 (ltu:DI (match_dup 1)
5914 (match_dup 2)))
5915 (set (match_dup 0)
5916 (xor:DI (match_dup 0)
5917 (const_int 1)))]
5918 "")
5919
5920 (define_expand "sltu"
5921 [(set (match_operand:SI 0 "register_operand" "=d")
5922 (ltu:SI (match_dup 1)
5923 (match_dup 2)))]
5924 ""
5925 "
5926 {
5927 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5928 FAIL;
5929
5930 /* set up operands from compare. */
5931 operands[1] = branch_cmp[0];
5932 operands[2] = branch_cmp[1];
5933
5934 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5935 {
5936 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
5937 DONE;
5938 }
5939
5940 /* fall through and generate default code */
5941 }")
5942
5943 (define_insn "sltu_si"
5944 [(set (match_operand:SI 0 "register_operand" "=d")
5945 (ltu:SI (match_operand:SI 1 "register_operand" "d")
5946 (match_operand:SI 2 "arith_operand" "dI")))]
5947 ""
5948 "sltu\\t%0,%1,%2"
5949 [(set_attr "type" "arith")
5950 (set_attr "mode" "SI")
5951 (set_attr "length" "1")])
5952
5953 (define_insn "sltu_di"
5954 [(set (match_operand:DI 0 "register_operand" "=d")
5955 (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
5956 (match_operand:DI 2 "se_arith_operand" "dI")))]
5957 "TARGET_64BIT"
5958 "sltu\\t%0,%1,%2"
5959 [(set_attr "type" "arith")
5960 (set_attr "mode" "DI")
5961 (set_attr "length" "1")])
5962
5963 (define_expand "sleu"
5964 [(set (match_operand:SI 0 "register_operand" "=d")
5965 (leu:SI (match_dup 1)
5966 (match_dup 2)))]
5967 ""
5968 "
5969 {
5970 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5971 FAIL;
5972
5973 /* set up operands from compare. */
5974 operands[1] = branch_cmp[0];
5975 operands[2] = branch_cmp[1];
5976
5977 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5978 {
5979 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
5980 DONE;
5981 }
5982
5983 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5984 operands[2] = force_reg (SImode, operands[2]);
5985
5986 /* fall through and generate default code */
5987 }")
5988
5989 (define_insn "sleu_si_const"
5990 [(set (match_operand:SI 0 "register_operand" "=d")
5991 (leu:SI (match_operand:SI 1 "register_operand" "d")
5992 (match_operand:SI 2 "small_int" "I")))]
5993 "INTVAL (operands[2]) < 32767"
5994 "*
5995 {
5996 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5997 return \"sltu\\t%0,%1,%2\";
5998 }"
5999 [(set_attr "type" "arith")
6000 (set_attr "mode" "SI")
6001 (set_attr "length" "1")])
6002
6003 (define_insn "sleu_di_const"
6004 [(set (match_operand:DI 0 "register_operand" "=d")
6005 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
6006 (match_operand:DI 2 "small_int" "I")))]
6007 "TARGET_64BIT && INTVAL (operands[2]) < 32767"
6008 "*
6009 {
6010 operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
6011 return \"sltu\\t%0,%1,%2\";
6012 }"
6013 [(set_attr "type" "arith")
6014 (set_attr "mode" "DI")
6015 (set_attr "length" "1")])
6016
6017 (define_insn "sleu_si_reg"
6018 [(set (match_operand:SI 0 "register_operand" "=d")
6019 (leu:SI (match_operand:SI 1 "register_operand" "d")
6020 (match_operand:SI 2 "register_operand" "d")))]
6021 "TARGET_DEBUG_C_MODE"
6022 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
6023 [(set_attr "type" "arith")
6024 (set_attr "mode" "SI")
6025 (set_attr "length" "2")])
6026
6027 (define_split
6028 [(set (match_operand:SI 0 "register_operand" "")
6029 (leu:SI (match_operand:SI 1 "register_operand" "")
6030 (match_operand:SI 2 "register_operand" "")))]
6031 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
6032 [(set (match_dup 0)
6033 (ltu:SI (match_dup 2)
6034 (match_dup 1)))
6035 (set (match_dup 0)
6036 (xor:SI (match_dup 0)
6037 (const_int 1)))]
6038 "")
6039
6040 (define_insn "sleu_di_reg"
6041 [(set (match_operand:DI 0 "register_operand" "=d")
6042 (leu:DI (match_operand:DI 1 "se_register_operand" "d")
6043 (match_operand:DI 2 "se_register_operand" "d")))]
6044 "TARGET_64BIT && TARGET_DEBUG_C_MODE"
6045 "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
6046 [(set_attr "type" "arith")
6047 (set_attr "mode" "DI")
6048 (set_attr "length" "2")])
6049
6050 (define_split
6051 [(set (match_operand:DI 0 "register_operand" "")
6052 (leu:DI (match_operand:DI 1 "se_register_operand" "")
6053 (match_operand:DI 2 "se_register_operand" "")))]
6054 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
6055 [(set (match_dup 0)
6056 (ltu:DI (match_dup 2)
6057 (match_dup 1)))
6058 (set (match_dup 0)
6059 (xor:DI (match_dup 0)
6060 (const_int 1)))]
6061 "")
6062
6063 \f
6064 ;;
6065 ;; ....................
6066 ;;
6067 ;; FLOATING POINT COMPARISONS
6068 ;;
6069 ;; ....................
6070
6071 (define_insn "seq_df"
6072 [(set (match_operand:CC 0 "register_operand" "=z")
6073 (eq:CC (match_operand:DF 1 "register_operand" "f")
6074 (match_operand:DF 2 "register_operand" "f")))]
6075 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6076 "*
6077 {
6078 return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6079 }"
6080 [(set_attr "type" "fcmp")
6081 (set_attr "mode" "FPSW")
6082 (set_attr "length" "1")])
6083
6084 (define_insn "slt_df"
6085 [(set (match_operand:CC 0 "register_operand" "=z")
6086 (lt:CC (match_operand:DF 1 "register_operand" "f")
6087 (match_operand:DF 2 "register_operand" "f")))]
6088 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6089 "*
6090 {
6091 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6092 }"
6093 [(set_attr "type" "fcmp")
6094 (set_attr "mode" "FPSW")
6095 (set_attr "length" "1")])
6096
6097 (define_insn "sle_df"
6098 [(set (match_operand:CC 0 "register_operand" "=z")
6099 (le:CC (match_operand:DF 1 "register_operand" "f")
6100 (match_operand:DF 2 "register_operand" "f")))]
6101 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6102 "*
6103 {
6104 return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6105 }"
6106 [(set_attr "type" "fcmp")
6107 (set_attr "mode" "FPSW")
6108 (set_attr "length" "1")])
6109
6110 (define_insn "sgt_df"
6111 [(set (match_operand:CC 0 "register_operand" "=z")
6112 (gt:CC (match_operand:DF 1 "register_operand" "f")
6113 (match_operand:DF 2 "register_operand" "f")))]
6114 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6115 "*
6116 {
6117 return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6118 }"
6119 [(set_attr "type" "fcmp")
6120 (set_attr "mode" "FPSW")
6121 (set_attr "length" "1")])
6122
6123 (define_insn "sge_df"
6124 [(set (match_operand:CC 0 "register_operand" "=z")
6125 (ge:CC (match_operand:DF 1 "register_operand" "f")
6126 (match_operand:DF 2 "register_operand" "f")))]
6127 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6128 "*
6129 {
6130 return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6131 }"
6132 [(set_attr "type" "fcmp")
6133 (set_attr "mode" "FPSW")
6134 (set_attr "length" "1")])
6135
6136 (define_insn "seq_sf"
6137 [(set (match_operand:CC 0 "register_operand" "=z")
6138 (eq:CC (match_operand:SF 1 "register_operand" "f")
6139 (match_operand:SF 2 "register_operand" "f")))]
6140 "TARGET_HARD_FLOAT"
6141 "*
6142 {
6143 return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6144 }"
6145 [(set_attr "type" "fcmp")
6146 (set_attr "mode" "FPSW")
6147 (set_attr "length" "1")])
6148
6149 (define_insn "slt_sf"
6150 [(set (match_operand:CC 0 "register_operand" "=z")
6151 (lt:CC (match_operand:SF 1 "register_operand" "f")
6152 (match_operand:SF 2 "register_operand" "f")))]
6153 "TARGET_HARD_FLOAT"
6154 "*
6155 {
6156 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6157 }"
6158 [(set_attr "type" "fcmp")
6159 (set_attr "mode" "FPSW")
6160 (set_attr "length" "1")])
6161
6162 (define_insn "sle_sf"
6163 [(set (match_operand:CC 0 "register_operand" "=z")
6164 (le:CC (match_operand:SF 1 "register_operand" "f")
6165 (match_operand:SF 2 "register_operand" "f")))]
6166 "TARGET_HARD_FLOAT"
6167 "*
6168 {
6169 return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6170 }"
6171 [(set_attr "type" "fcmp")
6172 (set_attr "mode" "FPSW")
6173 (set_attr "length" "1")])
6174
6175 (define_insn "sgt_sf"
6176 [(set (match_operand:CC 0 "register_operand" "=z")
6177 (gt:CC (match_operand:SF 1 "register_operand" "f")
6178 (match_operand:SF 2 "register_operand" "f")))]
6179 "TARGET_HARD_FLOAT"
6180 "*
6181 {
6182 return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6183 }"
6184 [(set_attr "type" "fcmp")
6185 (set_attr "mode" "FPSW")
6186 (set_attr "length" "1")])
6187
6188 (define_insn "sge_sf"
6189 [(set (match_operand:CC 0 "register_operand" "=z")
6190 (ge:CC (match_operand:SF 1 "register_operand" "f")
6191 (match_operand:SF 2 "register_operand" "f")))]
6192 "TARGET_HARD_FLOAT"
6193 "*
6194 {
6195 return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6196 }"
6197 [(set_attr "type" "fcmp")
6198 (set_attr "mode" "FPSW")
6199 (set_attr "length" "1")])
6200
6201 \f
6202 ;;
6203 ;; ....................
6204 ;;
6205 ;; UNCONDITIONAL BRANCHES
6206 ;;
6207 ;; ....................
6208
6209 ;; Unconditional branches.
6210
6211 (define_insn "jump"
6212 [(set (pc)
6213 (label_ref (match_operand 0 "" "")))]
6214 ""
6215 "*
6216 {
6217 if (GET_CODE (operands[0]) == REG)
6218 return \"%*j\\t%0\";
6219 /* ??? I don't know why this is necessary. This works around an
6220 assembler problem that appears when a label is defined, then referenced
6221 in a switch table, then used in a `j' instruction. */
6222 else if (mips_abi != ABI_32)
6223 return \"%*b\\t%l0\";
6224 else
6225 return \"%*j\\t%l0\";
6226 }"
6227 [(set_attr "type" "jump")
6228 (set_attr "mode" "none")
6229 (set_attr "length" "1")])
6230
6231 (define_expand "indirect_jump"
6232 [(set (pc) (match_operand 0 "register_operand" "d"))]
6233 ""
6234 "
6235 {
6236 rtx dest;
6237
6238 if (operands[0]) /* eliminate unused code warnings */
6239 {
6240 dest = operands[0];
6241 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6242 operands[0] = copy_to_mode_reg (Pmode, dest);
6243
6244 if (!TARGET_LONG64)
6245 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6246 else
6247 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6248
6249 DONE;
6250 }
6251 }")
6252
6253 (define_insn "indirect_jump_internal1"
6254 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6255 "!TARGET_LONG64"
6256 "%*j\\t%0"
6257 [(set_attr "type" "jump")
6258 (set_attr "mode" "none")
6259 (set_attr "length" "1")])
6260
6261 (define_insn "indirect_jump_internal2"
6262 [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
6263 "TARGET_LONG64"
6264 "%*j\\t%0"
6265 [(set_attr "type" "jump")
6266 (set_attr "mode" "none")
6267 (set_attr "length" "1")])
6268
6269 (define_expand "tablejump"
6270 [(set (pc)
6271 (match_operand 0 "register_operand" "d"))
6272 (use (label_ref (match_operand 1 "" "")))]
6273 ""
6274 "
6275 {
6276 rtx dest;
6277
6278 if (operands[0]) /* eliminate unused code warnings */
6279 {
6280 if (GET_MODE (operands[0]) != Pmode)
6281 abort ();
6282
6283 if (! flag_pic)
6284 {
6285 if (!TARGET_LONG64)
6286 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6287 else
6288 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6289 }
6290 else
6291 {
6292 if (!TARGET_LONG64)
6293 emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
6294 else
6295 emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
6296 }
6297
6298 DONE;
6299 }
6300 }")
6301
6302 (define_insn "tablejump_internal1"
6303 [(set (pc)
6304 (match_operand:SI 0 "register_operand" "d"))
6305 (use (label_ref (match_operand 1 "" "")))]
6306 "!TARGET_LONG64"
6307 "%*j\\t%0"
6308 [(set_attr "type" "jump")
6309 (set_attr "mode" "none")
6310 (set_attr "length" "1")])
6311
6312 (define_insn "tablejump_internal2"
6313 [(set (pc)
6314 (match_operand:DI 0 "se_register_operand" "d"))
6315 (use (label_ref (match_operand 1 "" "")))]
6316 "TARGET_LONG64"
6317 "%*j\\t%0"
6318 [(set_attr "type" "jump")
6319 (set_attr "mode" "none")
6320 (set_attr "length" "1")])
6321
6322 (define_expand "tablejump_internal3"
6323 [(set (pc)
6324 (plus:SI (match_operand:SI 0 "register_operand" "d")
6325 (label_ref:SI (match_operand:SI 1 "" ""))))]
6326 ""
6327 "")
6328
6329 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
6330 ;;; it is not valid.
6331
6332 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
6333 ;;; We just use the conservative number here.
6334
6335 (define_insn ""
6336 [(set (pc)
6337 (plus:SI (match_operand:SI 0 "register_operand" "d")
6338 (label_ref:SI (match_operand:SI 1 "" ""))))]
6339 "!TARGET_LONG64 && next_active_insn (insn) != 0
6340 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
6341 && PREV_INSN (next_active_insn (insn)) == operands[1]"
6342 "*
6343 {
6344 /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
6345 if (mips_abi == ABI_32)
6346 output_asm_insn (\".cpadd\\t%0\", operands);
6347 return \"%*j\\t%0\";
6348 }"
6349 [(set_attr "type" "jump")
6350 (set_attr "mode" "none")
6351 (set_attr "length" "2")])
6352
6353 (define_expand "tablejump_internal4"
6354 [(set (pc)
6355 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
6356 (label_ref:DI (match_operand:SI 1 "" ""))))]
6357 ""
6358 "")
6359
6360 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
6361 ;;; it is not valid.
6362
6363 (define_insn ""
6364 [(set (pc)
6365 (plus:DI (match_operand:DI 0 "se_register_operand" "d")
6366 (label_ref:DI (match_operand:SI 1 "" ""))))]
6367 "TARGET_LONG64 && next_active_insn (insn) != 0
6368 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
6369 && PREV_INSN (next_active_insn (insn)) == operands[1]"
6370 "%*j\\t%0"
6371 [(set_attr "type" "jump")
6372 (set_attr "mode" "none")
6373 (set_attr "length" "1")])
6374
6375 ;; Implement a switch statement when generating embedded PIC code.
6376 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
6377
6378 (define_expand "casesi"
6379 [(set (match_dup 5)
6380 (minus:SI (match_operand:SI 0 "register_operand" "d")
6381 (match_operand:SI 1 "arith_operand" "dI")))
6382 (set (cc0)
6383 (compare:CC (match_dup 5)
6384 (match_operand:SI 2 "arith_operand" "")))
6385 (set (pc)
6386 (if_then_else (gtu (cc0)
6387 (const_int 0))
6388 (label_ref (match_operand 4 "" ""))
6389 (pc)))
6390 (parallel
6391 [(set (pc)
6392 (mem:SI (plus:SI (mult:SI (match_dup 5)
6393 (const_int 4))
6394 (label_ref (match_operand 3 "" "")))))
6395 (clobber (match_scratch:SI 6 ""))
6396 (clobber (reg:SI 31))])]
6397 "TARGET_EMBEDDED_PIC"
6398 "
6399 {
6400 /* We need slightly different code for eight byte table entries. */
6401 if (TARGET_LONG64)
6402 abort ();
6403
6404 if (operands[0])
6405 {
6406 rtx reg = gen_reg_rtx (SImode);
6407
6408 /* If the index is too large, go to the default label. */
6409 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
6410 emit_insn (gen_cmpsi (reg, operands[2]));
6411 emit_insn (gen_bgtu (operands[4]));
6412
6413 /* Do the PIC jump. */
6414 emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
6415
6416 DONE;
6417 }
6418 }")
6419
6420 ;; An embedded PIC switch statement looks like this:
6421 ;; bal $LS1
6422 ;; sll $reg,$index,2
6423 ;; $LS1:
6424 ;; addu $reg,$reg,$31
6425 ;; lw $reg,$L1-$LS1($reg)
6426 ;; addu $reg,$reg,$31
6427 ;; j $reg
6428 ;; $L1:
6429 ;; .word case1-$LS1
6430 ;; .word case2-$LS1
6431 ;; ...
6432
6433 (define_insn "casesi_internal"
6434 [(set (pc)
6435 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
6436 (const_int 4))
6437 (label_ref (match_operand 1 "" "")))))
6438 (clobber (match_operand:SI 2 "register_operand" "d"))
6439 (clobber (reg:SI 31))]
6440 "TARGET_EMBEDDED_PIC"
6441 "*
6442 {
6443 output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
6444 output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
6445 output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
6446 return \"j\\t%0\";
6447 }"
6448 [(set_attr "type" "jump")
6449 (set_attr "mode" "none")
6450 (set_attr "length" "6")])
6451
6452 ;; ??? This is a hack to work around a problem with expand_builtin_setjmp.
6453 ;; It restores the frame pointer, and then does a call to restore the global
6454 ;; pointer (gp) register. The call insn implicitly (via the assembler) reloads
6455 ;; gp from the stack. However, call insns do not depend on $fp, so it is
6456 ;; possible for the instruction scheduler to move the fp restore after the
6457 ;; call, which then causes gp to be corrupted. We fix this by emitting a
6458 ;; scheduler barrier. A better fix is to put code here that restores the
6459 ;; $gp, and then the call is unnecessary. This is only a problem when PIC
6460 ;; (TARGET_ABICALLS), and only when the gp register is caller-saved
6461 ;; (irix5/o32, but not irix6/n32/n64).
6462
6463 (define_expand "nonlocal_goto_receiver"
6464 [(const_int 0)]
6465 ""
6466 "
6467 {
6468 emit_insn (gen_blockage ());
6469 }")
6470 \f
6471 ;;
6472 ;; ....................
6473 ;;
6474 ;; Function prologue/epilogue
6475 ;;
6476 ;; ....................
6477 ;;
6478
6479 (define_expand "prologue"
6480 [(const_int 1)]
6481 ""
6482 "
6483 {
6484 if (mips_isa >= 0) /* avoid unused code warnings */
6485 {
6486 mips_expand_prologue ();
6487 DONE;
6488 }
6489 }")
6490
6491 ;; Block any insns from being moved before this point, since the
6492 ;; profiling call to mcount can use various registers that aren't
6493 ;; saved or used to pass arguments.
6494
6495 (define_insn "blockage"
6496 [(unspec_volatile [(const_int 0)] 0)]
6497 ""
6498 ""
6499 [(set_attr "type" "unknown")
6500 (set_attr "mode" "none")
6501 (set_attr "length" "0")])
6502
6503 (define_expand "epilogue"
6504 [(const_int 2)]
6505 ""
6506 "
6507 {
6508 if (mips_isa >= 0) /* avoid unused code warnings */
6509 {
6510 mips_expand_epilogue ();
6511 DONE;
6512 }
6513 }")
6514
6515 ;; Trivial return. Make it look like a normal return insn as that
6516 ;; allows jump optimizations to work better .
6517 (define_insn "return"
6518 [(return)]
6519 "mips_can_use_return_insn ()"
6520 "%*j\\t$31"
6521 [(set_attr "type" "jump")
6522 (set_attr "mode" "none")
6523 (set_attr "length" "1")])
6524
6525 ;; Normal return.
6526 (define_insn "return_internal"
6527 [(use (reg:SI 31))
6528 (return)]
6529 ""
6530 "%*j\\t$31"
6531 [(set_attr "type" "jump")
6532 (set_attr "mode" "none")
6533 (set_attr "length" "1")])
6534
6535 ;; When generating embedded PIC code we need to get the address of the
6536 ;; current function. This specialized instruction does just that.
6537
6538 (define_insn "get_fnaddr"
6539 [(set (match_operand 0 "register_operand" "=d")
6540 (unspec [(match_operand 1 "" "")] 1))
6541 (clobber (reg:SI 31))]
6542 "TARGET_EMBEDDED_PIC
6543 && GET_CODE (operands[1]) == SYMBOL_REF"
6544 "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
6545 [(set_attr "type" "call")
6546 (set_attr "mode" "none")
6547 (set_attr "length" "4")])
6548
6549 \f
6550 ;;
6551 ;; ....................
6552 ;;
6553 ;; FUNCTION CALLS
6554 ;;
6555 ;; ....................
6556
6557 ;; calls.c now passes a third argument, make saber happy
6558
6559 (define_expand "call"
6560 [(parallel [(call (match_operand 0 "memory_operand" "m")
6561 (match_operand 1 "" "i"))
6562 (clobber (reg:SI 31))
6563 (use (match_operand 2 "" "")) ;; next_arg_reg
6564 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
6565 ""
6566 "
6567 {
6568 rtx addr;
6569
6570 if (operands[0]) /* eliminate unused code warnings */
6571 {
6572 addr = XEXP (operands[0], 0);
6573 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6574 || ! call_insn_operand (addr, VOIDmode))
6575 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
6576
6577 /* In order to pass small structures by value in registers
6578 compatibly with the MIPS compiler, we need to shift the value
6579 into the high part of the register. Function_arg has encoded
6580 a PARALLEL rtx, holding a vector of adjustments to be made
6581 as the next_arg_reg variable, so we split up the insns,
6582 and emit them separately. */
6583
6584 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
6585 {
6586 rtvec adjust = XVEC (operands[2], 0);
6587 int num = GET_NUM_ELEM (adjust);
6588 int i;
6589
6590 for (i = 0; i < num; i++)
6591 emit_insn (RTVEC_ELT (adjust, i));
6592 }
6593
6594 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
6595 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6596 DONE;
6597 }
6598 }")
6599
6600 (define_expand "call_internal0"
6601 [(parallel [(call (match_operand 0 "" "")
6602 (match_operand 1 "" ""))
6603 (clobber (match_operand:SI 2 "" ""))])]
6604 ""
6605 "")
6606
6607 (define_insn "call_internal1"
6608 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
6609 (match_operand 1 "" "i"))
6610 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6611 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6612 "*
6613 {
6614 register rtx target = operands[0];
6615
6616 if (GET_CODE (target) == SYMBOL_REF)
6617 return \"%*jal\\t%0\";
6618 else if (GET_CODE (target) == CONST_INT)
6619 return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
6620 else
6621 return \"%*jal\\t%2,%0\";
6622 }"
6623 [(set_attr "type" "call")
6624 (set_attr "mode" "none")
6625 (set_attr "length" "1")])
6626
6627 (define_insn "call_internal2"
6628 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
6629 (match_operand 1 "" "i"))
6630 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6631 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6632 "*
6633 {
6634 register rtx target = operands[0];
6635
6636 if (GET_CODE (target) == SYMBOL_REF)
6637 {
6638 if (GET_MODE (target) == SImode)
6639 return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
6640 else
6641 return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
6642 }
6643 else if (GET_CODE (target) == CONST_INT)
6644 return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
6645 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6646 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6647 else
6648 return \"jal\\t%2,%0\";
6649 }"
6650 [(set_attr "type" "call")
6651 (set_attr "mode" "none")
6652 (set_attr "length" "2")])
6653
6654 (define_insn "call_internal3a"
6655 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6656 (match_operand 1 "" "i"))
6657 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6658 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6659 "%*jal\\t%2,%0"
6660 [(set_attr "type" "call")
6661 (set_attr "mode" "none")
6662 (set_attr "length" "1")])
6663
6664 (define_insn "call_internal3b"
6665 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
6666 (match_operand 1 "" "i"))
6667 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6668 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6669 "%*jal\\t%2,%0"
6670 [(set_attr "type" "call")
6671 (set_attr "mode" "none")
6672 (set_attr "length" "1")])
6673
6674 (define_insn "call_internal4a"
6675 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6676 (match_operand 1 "" "i"))
6677 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6678 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6679 "*
6680 {
6681 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6682 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6683 else
6684 return \"jal\\t%2,%0\";
6685 }"
6686 [(set_attr "type" "call")
6687 (set_attr "mode" "none")
6688 (set_attr "length" "2")])
6689
6690 (define_insn "call_internal4b"
6691 [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
6692 (match_operand 1 "" "i"))
6693 (clobber (match_operand:SI 2 "register_operand" "=d"))]
6694 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6695 "*
6696 {
6697 if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6698 return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6699 else
6700 return \"jal\\t%2,%0\";
6701 }"
6702 [(set_attr "type" "call")
6703 (set_attr "mode" "none")
6704 (set_attr "length" "2")])
6705
6706 ;; calls.c now passes a fourth argument, make saber happy
6707
6708 (define_expand "call_value"
6709 [(parallel [(set (match_operand 0 "register_operand" "=df")
6710 (call (match_operand 1 "memory_operand" "m")
6711 (match_operand 2 "" "i")))
6712 (clobber (reg:SI 31))
6713 (use (match_operand 3 "" ""))])] ;; next_arg_reg
6714 ""
6715 "
6716 {
6717 rtx addr;
6718
6719 if (operands[0]) /* eliminate unused code warning */
6720 {
6721 addr = XEXP (operands[1], 0);
6722 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6723 || ! call_insn_operand (addr, VOIDmode))
6724 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
6725
6726 /* In order to pass small structures by value in registers
6727 compatibly with the MIPS compiler, we need to shift the value
6728 into the high part of the register. Function_arg has encoded
6729 a PARALLEL rtx, holding a vector of adjustments to be made
6730 as the next_arg_reg variable, so we split up the insns,
6731 and emit them separately. */
6732
6733 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
6734 {
6735 rtvec adjust = XVEC (operands[3], 0);
6736 int num = GET_NUM_ELEM (adjust);
6737 int i;
6738
6739 for (i = 0; i < num; i++)
6740 emit_insn (RTVEC_ELT (adjust, i));
6741 }
6742
6743 /* Handle Irix6 function calls that have multiple non-contiguous
6744 results. */
6745 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
6746 {
6747 emit_call_insn (gen_call_value_multiple_internal0
6748 (XEXP (XVECEXP (operands[0], 0, 0), 0),
6749 operands[1], operands[2],
6750 XEXP (XVECEXP (operands[0], 0, 1), 0),
6751 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6752 DONE;
6753 }
6754
6755 /* We have a call returning a DImode structure in an FP reg.
6756 Strip off the now unnecessary PARALLEL. */
6757 if (GET_CODE (operands[0]) == PARALLEL)
6758 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
6759
6760 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
6761 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6762
6763 DONE;
6764 }
6765 }")
6766
6767 (define_expand "call_value_internal0"
6768 [(parallel [(set (match_operand 0 "" "")
6769 (call (match_operand 1 "" "")
6770 (match_operand 2 "" "")))
6771 (clobber (match_operand:SI 3 "" ""))])]
6772 ""
6773 "")
6774
6775 (define_insn "call_value_internal1"
6776 [(set (match_operand 0 "register_operand" "=df")
6777 (call (mem (match_operand 1 "call_insn_operand" "ri"))
6778 (match_operand 2 "" "i")))
6779 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6780 "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6781 "*
6782 {
6783 register rtx target = operands[1];
6784
6785 if (GET_CODE (target) == SYMBOL_REF)
6786 return \"%*jal\\t%1\";
6787 else if (GET_CODE (target) == CONST_INT)
6788 return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
6789 else
6790 return \"%*jal\\t%3,%1\";
6791 }"
6792 [(set_attr "type" "call")
6793 (set_attr "mode" "none")
6794 (set_attr "length" "1")])
6795
6796 (define_insn "call_value_internal2"
6797 [(set (match_operand 0 "register_operand" "=df")
6798 (call (mem (match_operand 1 "call_insn_operand" "ri"))
6799 (match_operand 2 "" "i")))
6800 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6801 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6802 "*
6803 {
6804 register rtx target = operands[1];
6805
6806 if (GET_CODE (target) == SYMBOL_REF)
6807 {
6808 if (GET_MODE (target) == SImode)
6809 return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
6810 else
6811 return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
6812 }
6813 else if (GET_CODE (target) == CONST_INT)
6814 return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
6815 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6816 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6817 else
6818 return \"jal\\t%3,%1\";
6819 }"
6820 [(set_attr "type" "call")
6821 (set_attr "mode" "none")
6822 (set_attr "length" "2")])
6823
6824 (define_insn "call_value_internal3a"
6825 [(set (match_operand 0 "register_operand" "=df")
6826 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6827 (match_operand 2 "" "i")))
6828 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6829 "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6830 "%*jal\\t%3,%1"
6831 [(set_attr "type" "call")
6832 (set_attr "mode" "none")
6833 (set_attr "length" "1")])
6834
6835 (define_insn "call_value_internal3b"
6836 [(set (match_operand 0 "register_operand" "=df")
6837 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
6838 (match_operand 2 "" "i")))
6839 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6840 "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6841 "%*jal\\t%3,%1"
6842 [(set_attr "type" "call")
6843 (set_attr "mode" "none")
6844 (set_attr "length" "1")])
6845
6846 (define_insn "call_value_internal4a"
6847 [(set (match_operand 0 "register_operand" "=df")
6848 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6849 (match_operand 2 "" "i")))
6850 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6851 "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6852 "*
6853 {
6854 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6855 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6856 else
6857 return \"jal\\t%3,%1\";
6858 }"
6859 [(set_attr "type" "call")
6860 (set_attr "mode" "none")
6861 (set_attr "length" "2")])
6862
6863 (define_insn "call_value_internal4b"
6864 [(set (match_operand 0 "register_operand" "=df")
6865 (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
6866 (match_operand 2 "" "i")))
6867 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6868 "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6869 "*
6870 {
6871 if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6872 return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6873 else
6874 return \"jal\\t%3,%1\";
6875 }"
6876 [(set_attr "type" "call")
6877 (set_attr "mode" "none")
6878 (set_attr "length" "2")])
6879
6880 (define_expand "call_value_multiple_internal0"
6881 [(parallel [(set (match_operand 0 "" "")
6882 (call (match_operand 1 "" "")
6883 (match_operand 2 "" "")))
6884 (set (match_operand 3 "" "")
6885 (call (match_dup 1)
6886 (match_dup 2)))
6887 (clobber (match_operand:SI 4 "" ""))])]
6888 ""
6889 "")
6890
6891 ;; ??? May eventually need all 6 versions of the call patterns with multiple
6892 ;; return values.
6893
6894 (define_insn "call_value_multiple_internal2"
6895 [(set (match_operand 0 "register_operand" "=df")
6896 (call (mem (match_operand 1 "call_insn_operand" "ri"))
6897 (match_operand 2 "" "i")))
6898 (set (match_operand 3 "register_operand" "=df")
6899 (call (mem (match_dup 1))
6900 (match_dup 2)))
6901 (clobber (match_operand:SI 4 "register_operand" "=d"))]
6902 "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6903 "*
6904 {
6905 register rtx target = operands[1];
6906
6907 if (GET_CODE (target) == SYMBOL_REF)
6908 {
6909 if (GET_MODE (target) == SImode)
6910 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
6911 else
6912 return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
6913 }
6914 else if (GET_CODE (target) == CONST_INT)
6915 return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
6916 else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6917 return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
6918 else
6919 return \"jal\\t%4,%1\";
6920 }"
6921 [(set_attr "type" "call")
6922 (set_attr "mode" "none")
6923 (set_attr "length" "2")])
6924
6925
6926 ;; Call subroutine returning any type.
6927
6928 (define_expand "untyped_call"
6929 [(parallel [(call (match_operand 0 "" "")
6930 (const_int 0))
6931 (match_operand 1 "" "")
6932 (match_operand 2 "" "")])]
6933 ""
6934 "
6935 {
6936 if (operands[0]) /* silence statement not reached warnings */
6937 {
6938 int i;
6939
6940 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
6941
6942 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6943 {
6944 rtx set = XVECEXP (operands[2], 0, i);
6945 emit_move_insn (SET_DEST (set), SET_SRC (set));
6946 }
6947
6948 emit_insn (gen_blockage ());
6949 DONE;
6950 }
6951 }")
6952 \f
6953 ;;
6954 ;; ....................
6955 ;;
6956 ;; MISC.
6957 ;;
6958 ;; ....................
6959 ;;
6960
6961 (define_insn "nop"
6962 [(const_int 0)]
6963 ""
6964 "%(nop%)"
6965 [(set_attr "type" "nop")
6966 (set_attr "mode" "none")
6967 (set_attr "length" "1")])
6968
6969 ;; The MIPS chip does not seem to require stack probes.
6970 ;;
6971 ;; (define_expand "probe"
6972 ;; [(set (match_dup 0)
6973 ;; (match_dup 1))]
6974 ;; ""
6975 ;; "
6976 ;; {
6977 ;; operands[0] = gen_reg_rtx (SImode);
6978 ;; operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
6979 ;; MEM_VOLATILE_P (operands[1]) = TRUE;
6980 ;;
6981 ;; /* fall through and generate default code */
6982 ;; }")
6983 ;;
6984 \f
6985 ;;
6986 ;; MIPS4 Conditional move instructions.
6987
6988 (define_insn ""
6989 [(set (match_operand:SI 0 "register_operand" "=d,d")
6990 (if_then_else:SI
6991 (match_operator 4 "equality_op"
6992 [(match_operand:SI 1 "register_operand" "d,d")
6993 (const_int 0)])
6994 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6995 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6996 "mips_isa >= 4"
6997 "@
6998 mov%B4\\t%0,%z2,%1
6999 mov%b4\\t%0,%z3,%1"
7000 [(set_attr "type" "move")
7001 (set_attr "mode" "SI")])
7002
7003 (define_insn ""
7004 [(set (match_operand:SI 0 "register_operand" "=d,d")
7005 (if_then_else:SI
7006 (match_operator 4 "equality_op"
7007 [(match_operand:DI 1 "se_register_operand" "d,d")
7008 (const_int 0)])
7009 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7010 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7011 "mips_isa >= 4"
7012 "@
7013 mov%B4\\t%0,%z2,%1
7014 mov%b4\\t%0,%z3,%1"
7015 [(set_attr "type" "move")
7016 (set_attr "mode" "SI")])
7017
7018 (define_insn ""
7019 [(set (match_operand:SI 0 "register_operand" "=d,d")
7020 (if_then_else:SI
7021 (match_operator 3 "equality_op" [(match_operand:CC 4
7022 "register_operand"
7023 "z,z")
7024 (const_int 0)])
7025 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7026 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7027 "mips_isa >= 4 && TARGET_HARD_FLOAT"
7028 "@
7029 mov%T3\\t%0,%z1,%4
7030 mov%t3\\t%0,%z2,%4"
7031 [(set_attr "type" "move")
7032 (set_attr "mode" "SI")])
7033
7034 (define_insn ""
7035 [(set (match_operand:DI 0 "register_operand" "=d,d")
7036 (if_then_else:DI
7037 (match_operator 4 "equality_op"
7038 [(match_operand:SI 1 "register_operand" "d,d")
7039 (const_int 0)])
7040 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
7041 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
7042 "mips_isa >= 4"
7043 "@
7044 mov%B4\\t%0,%z2,%1
7045 mov%b4\\t%0,%z3,%1"
7046 [(set_attr "type" "move")
7047 (set_attr "mode" "DI")])
7048
7049 (define_insn ""
7050 [(set (match_operand:DI 0 "register_operand" "=d,d")
7051 (if_then_else:DI
7052 (match_operator 4 "equality_op"
7053 [(match_operand:DI 1 "se_register_operand" "d,d")
7054 (const_int 0)])
7055 (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
7056 (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
7057 "mips_isa >= 4"
7058 "@
7059 mov%B4\\t%0,%z2,%1
7060 mov%b4\\t%0,%z3,%1"
7061 [(set_attr "type" "move")
7062 (set_attr "mode" "DI")])
7063
7064 (define_insn ""
7065 [(set (match_operand:DI 0 "register_operand" "=d,d")
7066 (if_then_else:DI
7067 (match_operator 3 "equality_op" [(match_operand:CC 4
7068 "register_operand"
7069 "z,z")
7070 (const_int 0)])
7071 (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
7072 (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
7073 "mips_isa >= 4 && TARGET_HARD_FLOAT"
7074 "@
7075 mov%T3\\t%0,%z1,%4
7076 mov%t3\\t%0,%z2,%4"
7077 [(set_attr "type" "move")
7078 (set_attr "mode" "DI")])
7079
7080 (define_insn ""
7081 [(set (match_operand:SF 0 "register_operand" "=f,f")
7082 (if_then_else:SF
7083 (match_operator 4 "equality_op"
7084 [(match_operand:SI 1 "register_operand" "d,d")
7085 (const_int 0)])
7086 (match_operand:SF 2 "register_operand" "f,0")
7087 (match_operand:SF 3 "register_operand" "0,f")))]
7088 "mips_isa >= 4 && TARGET_HARD_FLOAT"
7089 "@
7090 mov%B4.s\\t%0,%2,%1
7091 mov%b4.s\\t%0,%3,%1"
7092 [(set_attr "type" "move")
7093 (set_attr "mode" "SF")])
7094
7095 (define_insn ""
7096 [(set (match_operand:SF 0 "register_operand" "=f,f")
7097 (if_then_else:SF
7098 (match_operator 3 "equality_op" [(match_operand:CC 4
7099 "register_operand"
7100 "z,z")
7101 (const_int 0)])
7102 (match_operand:SF 1 "register_operand" "f,0")
7103 (match_operand:SF 2 "register_operand" "0,f")))]
7104 "mips_isa >= 4 && TARGET_HARD_FLOAT"
7105 "@
7106 mov%T3.s\\t%0,%1,%4
7107 mov%t3.s\\t%0,%2,%4"
7108 [(set_attr "type" "move")
7109 (set_attr "mode" "SF")])
7110
7111 (define_insn ""
7112 [(set (match_operand:DF 0 "register_operand" "=f,f")
7113 (if_then_else:DF
7114 (match_operator 4 "equality_op"
7115 [(match_operand:SI 1 "register_operand" "d,d")
7116 (const_int 0)])
7117 (match_operand:DF 2 "register_operand" "f,0")
7118 (match_operand:DF 3 "register_operand" "0,f")))]
7119 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7120 "@
7121 mov%B4.d\\t%0,%2,%1
7122 mov%b4.d\\t%0,%3,%1"
7123 [(set_attr "type" "move")
7124 (set_attr "mode" "DF")])
7125
7126 (define_insn ""
7127 [(set (match_operand:DF 0 "register_operand" "=f,f")
7128 (if_then_else:DF
7129 (match_operator 3 "equality_op" [(match_operand:CC 4
7130 "register_operand"
7131 "z,z")
7132 (const_int 0)])
7133 (match_operand:DF 1 "register_operand" "f,0")
7134 (match_operand:DF 2 "register_operand" "0,f")))]
7135 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7136 "@
7137 mov%T3.d\\t%0,%1,%4
7138 mov%t3.d\\t%0,%2,%4"
7139 [(set_attr "type" "move")
7140 (set_attr "mode" "DF")])
7141
7142 ;; These are the main define_expand's used to make conditional moves.
7143
7144 (define_expand "movsicc"
7145 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7146 (set (match_operand:SI 0 "register_operand" "")
7147 (if_then_else:SI (match_dup 5)
7148 (match_operand:SI 2 "reg_or_0_operand" "")
7149 (match_operand:SI 3 "reg_or_0_operand" "")))]
7150 "mips_isa >= 4"
7151 "
7152 {
7153 gen_conditional_move (operands);
7154 DONE;
7155 }")
7156
7157 (define_expand "movdicc"
7158 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7159 (set (match_operand:DI 0 "register_operand" "")
7160 (if_then_else:DI (match_dup 5)
7161 (match_operand:DI 2 "se_reg_or_0_operand" "")
7162 (match_operand:DI 3 "se_reg_or_0_operand" "")))]
7163 "mips_isa >= 4"
7164 "
7165 {
7166 gen_conditional_move (operands);
7167 DONE;
7168 }")
7169
7170 (define_expand "movsfcc"
7171 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7172 (set (match_operand:SF 0 "register_operand" "")
7173 (if_then_else:SF (match_dup 5)
7174 (match_operand:SF 2 "register_operand" "")
7175 (match_operand:SF 3 "register_operand" "")))]
7176 "mips_isa >= 4 && TARGET_HARD_FLOAT"
7177 "
7178 {
7179 gen_conditional_move (operands);
7180 DONE;
7181 }")
7182
7183 (define_expand "movdfcc"
7184 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7185 (set (match_operand:DF 0 "register_operand" "")
7186 (if_then_else:DF (match_dup 5)
7187 (match_operand:DF 2 "register_operand" "")
7188 (match_operand:DF 3 "register_operand" "")))]
7189 "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7190 "
7191 {
7192 gen_conditional_move (operands);
7193 DONE;
7194 }")