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