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